From 5b740fbf60d9f9370726c622a91c7cde57d93d11 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Fri, 20 Jan 2023 14:35:46 -0600 Subject: [PATCH] Removed SDC from repo due to copy right issue. Modified fpga build flow to reference it outside the repo. --- .gitignore | 2 + fpga/generator/Makefile | 19 +- fpga/generator/wally.tcl | 1 + pipelined/src/uncore/sdc/SDC.sv | 362 ---------- pipelined/src/uncore/sdc/SDCcounter.sv | 43 -- pipelined/src/uncore/sdc/clkdivider.sv | 105 --- pipelined/src/uncore/sdc/crc16_sipo_np_ce.sv | 63 -- pipelined/src/uncore/sdc/crc7_pipo.sv | 67 -- pipelined/src/uncore/sdc/crc7_sipo_np_ce.sv | 60 -- pipelined/src/uncore/sdc/piso_generic_ce.sv | 49 -- .../src/uncore/sdc/regfile_p2r1w1_nibo.sv | 49 -- .../src/uncore/sdc/regfile_p2r1w1bwen.sv | 44 -- pipelined/src/uncore/sdc/sd_clk_fsm.sv | 93 --- pipelined/src/uncore/sdc/sd_cmd_fsm.sv | 586 ---------------- pipelined/src/uncore/sdc/sd_dat_fsm.sv | 253 ------- pipelined/src/uncore/sdc/sd_top.sv | 652 ------------------ pipelined/src/uncore/sdc/sd_top_wrapper.v | 98 --- pipelined/src/uncore/sdc/simple_timer.sv | 54 -- pipelined/src/uncore/sdc/sipo_generic_ce.sv | 51 -- pipelined/src/uncore/sdc/up_down_counter.sv | 45 -- 20 files changed, 15 insertions(+), 2681 deletions(-) delete mode 100644 pipelined/src/uncore/sdc/SDC.sv delete mode 100644 pipelined/src/uncore/sdc/SDCcounter.sv delete mode 100644 pipelined/src/uncore/sdc/clkdivider.sv delete mode 100644 pipelined/src/uncore/sdc/crc16_sipo_np_ce.sv delete mode 100644 pipelined/src/uncore/sdc/crc7_pipo.sv delete mode 100644 pipelined/src/uncore/sdc/crc7_sipo_np_ce.sv delete mode 100644 pipelined/src/uncore/sdc/piso_generic_ce.sv delete mode 100644 pipelined/src/uncore/sdc/regfile_p2r1w1_nibo.sv delete mode 100644 pipelined/src/uncore/sdc/regfile_p2r1w1bwen.sv delete mode 100644 pipelined/src/uncore/sdc/sd_clk_fsm.sv delete mode 100644 pipelined/src/uncore/sdc/sd_cmd_fsm.sv delete mode 100644 pipelined/src/uncore/sdc/sd_dat_fsm.sv delete mode 100644 pipelined/src/uncore/sdc/sd_top.sv delete mode 100644 pipelined/src/uncore/sdc/sd_top_wrapper.v delete mode 100644 pipelined/src/uncore/sdc/simple_timer.sv delete mode 100644 pipelined/src/uncore/sdc/sipo_generic_ce.sv delete mode 100644 pipelined/src/uncore/sdc/up_down_counter.sv diff --git a/.gitignore b/.gitignore index d4e9acd58..587fc73a5 100644 --- a/.gitignore +++ b/.gitignore @@ -126,3 +126,5 @@ tests/custom/*/*/*.map tests/custom/*/*/*.memfile tests/custom/crt0/*.a /pipelined/regression/sd_model.log +fpga/src/sdc/* +fpga/src/sdc.tar.gz diff --git a/fpga/generator/Makefile b/fpga/generator/Makefile index f39a9bce9..b61c51ed5 100644 --- a/fpga/generator/Makefile +++ b/fpga/generator/Makefile @@ -1,18 +1,19 @@ dst := IP +sdc_src := ~/repos/sdc.tar.gz # vcu118 -export XILINX_PART := xcvu9p-flga2104-2L-e -export XILINX_BOARD := xilinx.com:vcu118:part0:2.4 -export board := vcu118 +#export XILINX_PART := xcvu9p-flga2104-2L-e +#export XILINX_BOARD := xilinx.com:vcu118:part0:2.4 +#export board := vcu118 # vcu108 -#export XILINX_PART := xcvu095-ffva2104-2-e -#export XILINX_BOARD := xilinx.com:vcu108:part0:1.2 -#export board := vcu108 +export XILINX_PART := xcvu095-ffva2104-2-e +export XILINX_BOARD := xilinx.com:vcu108:part0:1.2 +export board := vcu108 all: FPGA -FPGA: IP +FPGA: IP SDC vivado -mode tcl -source wally.tcl 2>&1 | tee wally.log IP: $(dst)/xlnx_proc_sys_reset.log \ @@ -20,6 +21,10 @@ IP: $(dst)/xlnx_proc_sys_reset.log \ $(dst)/xlnx_axi_clock_converter.log \ $(dst)/xlnx_ahblite_axi_bridge.log +SDC: + cp $(sdc_src) ../src/ + tar xzf ../src/sdc.tar.gz -C ../src + $(dst)/%.log: %.tcl mkdir -p IP cd IP;\ diff --git a/fpga/generator/wally.tcl b/fpga/generator/wally.tcl index 6afa9e66f..b2597f60d 100644 --- a/fpga/generator/wally.tcl +++ b/fpga/generator/wally.tcl @@ -17,6 +17,7 @@ read_ip IP/xlnx_ddr4.srcs/sources_1/ip/xlnx_ddr4/xlnx_ddr4.xci read_verilog -sv [glob -type f ../../pipelined/src/*/*.sv ../../pipelined/src/*/*/*.sv] read_verilog {../src/fpgaTop.v} +read_verilog -sv [glob -type f ../src/sdc/*.sv] set_property include_dirs {../../pipelined/config/fpga ../../pipelined/config/shared} [current_fileset] diff --git a/pipelined/src/uncore/sdc/SDC.sv b/pipelined/src/uncore/sdc/SDC.sv deleted file mode 100644 index 5a10d6430..000000000 --- a/pipelined/src/uncore/sdc/SDC.sv +++ /dev/null @@ -1,362 +0,0 @@ -/////////////////////////////////////////// -// SDC.sv -// -// Written: Ross Thompson September 22, 2021 -// Modified: -// -// Purpose: SDC interface to AHBLite BUS. -// -// A component of the CORE-V-WALLY configurable RISC-V project. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - -`include "wally-config.vh" - -`define SDCCLKDIV -8'd3 - -module SDC ( - input logic HCLK, - input logic HRESETn, - input logic HSELSDC, - input logic [4:0] HADDR, - input logic HWRITE, - input logic HREADY, - input logic [1:0] HTRANS, - input logic [`XLEN-1:0] HWDATA, - output logic [`XLEN-1:0] HREADSDC, - output logic HRESPSDC, - output logic HREADYSDC, - - //sd card interface - // place the tristate drivers at the top. this level - // will use dedicated 1 direction ports. - output logic SDCCmdOut, - input logic SDCCmdIn, - output logic SDCCmdOE, - input logic [3:0] SDCDatIn, - output logic SDCCLK, - // interrupt to PLIC - output logic SDCIntM -); - - logic InitTrans; - logic RegRead; - logic RegWrite; - logic [4:0] HADDRDelay; - - - // Register outputs - logic signed [7:0] CLKDiv; - logic [2:0] Command; - logic [63:9] Address; - - - logic SDCDone; - - logic [2:0] ErrorCode; - logic InvalidCommand; - logic SDCBusy; - - logic StartCLKDivUpdate; - logic CLKDivUpdateEn; - logic SDCCLKEN; - logic CLKGate; - logic SDCCLKIn; - - - logic SDCDataValid; - logic [`XLEN-1:0] SDCReadData; - logic [`XLEN-1:0] SDCReadDataPreNibbleSwap; - logic [`XLEN-1:0] SDCWriteData; - logic FatalError; - - logic [4095:0] ReadData512Byte; - logic [`XLEN-1:0] ReadData512ByteWords [4096/`XLEN-1:0] ; - logic SDCInitialized; - logic SDCRestarting; - logic SDCLast; - - logic [$clog2(4096/`XLEN)-1:0] WordCount; - logic WordCountRst; - logic [5:0] Status; - logic CommandCompleted; - logic ReadDone; - - - - genvar index; - - assign HRESPSDC = 1'b0; - - // registers - //| Offset | Name | Size | Purpose | - //|--------+---------+--------+------------------------------------------------| - //| 0x0 | CLKDiv | 4 | Divide HCLK to produce SDCLK | - //| 0x4 | Status | 4 | Provide status to software | - //| 0x8 | Control | 4 | Send commands to SDC | - //| 0xC | Size | 4 | Size of data command (only 512 byte supported) | - //| 0x10 | address | 8 | address of operation | - //| 0x18 | data | XLEN/8 | Data Bus interface | - - // Status contains - // Status[0] initialized - // Status[1] Busy on read - // Status[2] invalid command - // Status[5:3] error code - - // control contains 3 bit command - // control[2:0] - // 000 nop op - // xx1 initialize - // 010 Write no implemented - // 100 Read - // 110 Atomic read/write not implemented - - // size is fixed to 512. Read only - - - // Currently using a mailbox style interface. Data is passed through the Data register (0x10) - // The card will support 3 operations - // 1. initialize - // 2. read - // 3. write - // all read and write operations will occur on 512 bytes (4096 bits) of data - // starting at the 512 byte aligned address in the address register This register - // is the byte address. - - // currently does not support writes - - assign InitTrans = HREADY & HSELSDC & HTRANS[1]; - //assign RegRead = InitTrans & ~HWRITE; - // register resolve combo loop - flopr #(1) RegReadReg(HCLK, ~HRESETn, InitTrans & ~HWRITE, RegRead); - // AHBLite Spec has write data 1 cycle after write command - flopr #(1) RegWriteReg(HCLK, ~HRESETn, InitTrans & HWRITE, RegWrite); - - flopenr #(5) HADDRReg(HCLK, ~HRESETn, InitTrans, HADDR, HADDRDelay); - - assign StartCLKDivUpdate = HADDRDelay == '0 & RegWrite; - - flopenl #(8) CLKDivReg(HCLK, ~HRESETn, CLKDivUpdateEn, HWDATA[7:0], `SDCCLKDIV, CLKDiv); - - // Control reg - flopenl #(3) CommandReg(HCLK, ~HRESETn, (HADDRDelay == 'h8 & RegWrite) | (CommandCompleted), - CommandCompleted ? '0 : HWDATA[2:0], '0, Command); - - if (`XLEN == 64) begin - flopenr #(64-9) AddressReg(HCLK, ~HRESETn, (HADDRDelay == 'h10 & RegWrite), - HWDATA[`XLEN-1:9], Address); - end else begin - flopenr #(32-9) AddressLowReg(HCLK, ~HRESETn, (HADDRDelay == 'h10 & RegWrite), - HWDATA[`XLEN-1:9], Address[31:9]); - flopenr #(32) AddressHighReg(HCLK, ~HRESETn, (HADDRDelay == 'h14 & RegWrite), - HWDATA, Address[63:32]); - end - - flopen #(`XLEN) DataReg(HCLK, (HADDRDelay == 'h18 & RegWrite), - HWDATA, SDCWriteData); - - assign InvalidCommand = (Command[2] | Command[1]) & Command[0]; - - assign Status = {ErrorCode, InvalidCommand, SDCBusy, SDCInitialized}; - - if(`XLEN == 64) begin - always_comb - case(HADDRDelay[4:0]) - 'h0: HREADSDC = {24'b0, CLKDiv, 26'b0, Status}; - 'h4: HREADSDC = {26'b0, Status, 29'b0, Command}; - 'h8: HREADSDC = {29'b0, Command, 32'h200}; - 'hC: HREADSDC = {32'h200, Address[31:9], 9'b0}; - 'h10: HREADSDC = {Address, 9'b0}; - 'h18: HREADSDC = SDCReadData; - default: HREADSDC = {24'b0, CLKDiv, 26'b0, Status}; - endcase // case (HADDRDelay[4:0]) - end else begin - always_comb - case(HADDRDelay[4:0]) - 'h0: HREADSDC = {24'b0, CLKDiv}; - 'h4: HREADSDC = {26'b0, Status}; - 'h8: HREADSDC = {29'b0, Command}; - 'hC: HREADSDC = 'h200; - 'h10: HREADSDC = {Address[31:9], 9'b0}; - 'h14: HREADSDC = Address[63:32]; - 'h18: HREADSDC = SDCReadData[31:0]; - default: HREADSDC = {24'b0, CLKDiv}; - endcase - end - - - for(index = 0; index < 4096/`XLEN; index++) begin - assign ReadData512ByteWords[index] = ReadData512Byte[(index+1)*`XLEN-1:index*`XLEN]; - end - - assign SDCReadDataPreNibbleSwap = ReadData512ByteWords[WordCount]; - if(`XLEN == 64) begin - assign SDCReadData = {SDCReadDataPreNibbleSwap[59:56], SDCReadDataPreNibbleSwap[63:60], - SDCReadDataPreNibbleSwap[51:48], SDCReadDataPreNibbleSwap[55:52], - SDCReadDataPreNibbleSwap[43:40], SDCReadDataPreNibbleSwap[47:44], - SDCReadDataPreNibbleSwap[35:32], SDCReadDataPreNibbleSwap[39:36], - SDCReadDataPreNibbleSwap[27:24], SDCReadDataPreNibbleSwap[31:28], - SDCReadDataPreNibbleSwap[19:16], SDCReadDataPreNibbleSwap[23:20], - SDCReadDataPreNibbleSwap[11:8], SDCReadDataPreNibbleSwap[15:12], - SDCReadDataPreNibbleSwap[3:0], SDCReadDataPreNibbleSwap[7:4]}; - end else begin - assign SDCReadData = {SDCReadDataPreNibbleSwap[27:24], SDCReadDataPreNibbleSwap[31:28], - SDCReadDataPreNibbleSwap[19:16], SDCReadDataPreNibbleSwap[23:20], - SDCReadDataPreNibbleSwap[11:8], SDCReadDataPreNibbleSwap[15:12], - SDCReadDataPreNibbleSwap[3:0], SDCReadDataPreNibbleSwap[7:4]}; - end - - flopenr #($clog2(4096/`XLEN)) WordCountReg - (.clk(HCLK), - .reset(~HRESETn | WordCountRst), - .en(HADDRDelay[4:0] == 'h18 & ReadDone), - .d(WordCount + 1'b1), - .q(WordCount)); - - - - typedef enum {STATE_READY, - - // clock update states - STATE_CLK_DIV1, - STATE_CLK_DIV2, - STATE_CLK_DIV3, - STATE_CLK_DIV4, - - // restart SDC - STATE_RESTART, - - // SDC operation - STATE_PROCESS_CMD, - - STATE_READ - } statetype; - - - statetype CurrState, NextState; - - always_ff @(posedge HCLK, negedge HRESETn) - if (~HRESETn) CurrState <= STATE_READY; - else CurrState <= NextState; - - always_comb begin - CLKDivUpdateEn = 1'b0; - HREADYSDC = 1'b0; - SDCCLKEN = 1'b1; - WordCountRst = 1'b0; - SDCBusy = 1'b0; - CommandCompleted = 1'b0; - ReadDone = 1'b0; - - case (CurrState) - STATE_READY : begin - if (StartCLKDivUpdate)begin - NextState = STATE_CLK_DIV1; - HREADYSDC = 1'b0; - end else if (Command[2] | Command[1]) begin - NextState = STATE_PROCESS_CMD; - HREADYSDC = 1'b0; - end else if(HADDRDelay[4:0] == 'h18 & RegRead) begin - NextState = STATE_READ; - HREADYSDC = 1'b0; - end else begin - NextState = STATE_READY; - HREADYSDC = 1'b1; - end - end - STATE_CLK_DIV1: begin - NextState = STATE_CLK_DIV2; - SDCCLKEN = 1'b0; - end - STATE_CLK_DIV2: begin - NextState = STATE_CLK_DIV3; - CLKDivUpdateEn = 1'b1; - SDCCLKEN = 1'b0; - end - STATE_CLK_DIV3: begin - NextState = STATE_CLK_DIV4; - SDCCLKEN = 1'b0; - end - STATE_CLK_DIV4: begin - NextState = STATE_READY; - end - STATE_PROCESS_CMD: begin - HREADYSDC = 1'b1; - WordCountRst = 1'b1; - SDCBusy = 1'b1; - if(SDCDataValid) begin - NextState = STATE_READY; - CommandCompleted = 1'b1; - end else begin - NextState = STATE_PROCESS_CMD; - CommandCompleted = 1'b0; - end - end - STATE_READ: begin - NextState = STATE_READY; - HREADYSDC = 1'b1; - ReadDone = 1'b1; - end - default: begin - NextState = STATE_READY; - end - endcase - end - - // clock generation divider - - clockgater clockgater(.E(SDCCLKEN), - .SE(1'b0), - .CLK(HCLK), - .ECLK(CLKGate)); - - - clkdivider #(8) clkdivider(.i_COUNT_IN_MAX(CLKDiv), - .i_EN(CLKDiv <= 0), // enable if < 0 (msb is 1) - .i_CLK(CLKGate), - .i_RST(~HRESETn | CLKDivUpdateEn), - .o_CLK(SDCCLKIn)); - -// assign SDCCLKIn = CLKGate; - - - // should always be 0 for real implementation, but for simulation set to 1. - logic LimitTimers; - assign LimitTimers = '0; - - sd_top sd_top(.CLK(SDCCLKIn), - .a_RST(~HRESETn), - .i_SD_CMD(SDCCmdIn), - .o_SD_CMD(SDCCmdOut), - .o_SD_CMD_OE(SDCCmdOE), - .i_SD_DAT(SDCDatIn), - .o_SD_CLK(SDCCLK), - .i_BLOCK_ADDR(Address[32:9]), - .o_READY_FOR_READ(SDCInitialized), - .o_SD_RESTARTING(SDCRestarting), - .i_READ_REQUEST(Command[2]), - .o_DATA_TO_CORE(), - .ReadData(ReadData512Byte), - .o_DATA_VALID(SDCDataValid), - .o_LAST_NIBBLE(SDCLast), - .o_ERROR_CODE_Q(ErrorCode), - .o_FATAL_ERROR(FatalError), - .i_COUNT_IN_MAX(-8'd62), - .LIMIT_SD_TIMERS(LimitTimers)); // *** must change this to 0 for real hardware. - - -endmodule - diff --git a/pipelined/src/uncore/sdc/SDCcounter.sv b/pipelined/src/uncore/sdc/SDCcounter.sv deleted file mode 100644 index de39ba2b0..000000000 --- a/pipelined/src/uncore/sdc/SDCcounter.sv +++ /dev/null @@ -1,43 +0,0 @@ -/////////////////////////////////////////// -// counter.sv -// -// Written: Richard Davis -// Modified: Ross Thompson -// Converted to SystemVerilog. -// -// Purpose: basic up counter -// -// A component of the CORE-V-WALLY configurable RISC-V project. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - -`include "wally-config.vh" - -module SDCcounter #(parameter integer WIDTH=32) ( - input logic [WIDTH-1:0] CountIn, - output logic [WIDTH-1:0] CountOut, - input logic Load, - input logic Enable, - input logic clk, - input logic reset -); - - logic [WIDTH-1:0] NextCount; - - assign NextCount = Load ? CountIn : (CountOut + 1'b1); - flopenr #(WIDTH) reg1(clk, reset, Enable | Load, NextCount, CountOut); -endmodule - - diff --git a/pipelined/src/uncore/sdc/clkdivider.sv b/pipelined/src/uncore/sdc/clkdivider.sv deleted file mode 100644 index c62258efb..000000000 --- a/pipelined/src/uncore/sdc/clkdivider.sv +++ /dev/null @@ -1,105 +0,0 @@ -/////////////////////////////////////////// -// clock divider.sv -// -// Written: Richard Davis -// Modified: Ross Thompson September 18, 2021 -// Converted to system verilog. -// -// Purpose: clock divider for sd flash -// -// A component of the CORE-V-WALLY configurable RISC-V project. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - -`include "wally-config.vh" - -module clkdivider #(parameter integer g_COUNT_WIDTH) ( - input logic [g_COUNT_WIDTH-1:0] i_COUNT_IN_MAX, //((Divide by value)/2) - 1 - input logic i_EN, //Enable frequency division of i_clk - input logic i_CLK, // 1.2 GHz Base clock - input logic i_RST, // at start: clears flip flop and loads counter, - // i_RST must NOT be a_RST, it needs to be synchronized with the 50 MHz Clock to load the - // counter's initial value - output logic o_CLK // frequency divided clock -); - - - logic [g_COUNT_WIDTH-1:0] r_count_out; // wider for sign - logic w_counter_overflowed; - - logic r_fd_Q; - logic w_fd_D; - - logic w_load; - - logic resetD, resetDD, resetPulse; - logic rstdd2, rstddn; - - assign w_load = resetPulse | w_counter_overflowed; // reload when zero occurs or when set by outside - - SDCcounter #(.WIDTH(g_COUNT_WIDTH)) // wider for sign, this way the (MSB /= '1') only for zero - my_counter (.clk(i_CLK), - .Load(w_load), // reload when zero occurs or when set by outside - .CountIn(i_COUNT_IN_MAX), // negative signed integer - .CountOut(r_count_out), - .Enable(1'b1), // ALWAYS COUNT - .reset(1'b0)); // no reset, only load - - - assign w_counter_overflowed = r_count_out[g_COUNT_WIDTH-1] == '0; - - // to ensure the clock keeps running we need to make the reset last 1 cycle - // rather than until the reset is released. Alternatively we could do - // two resets. The first which resets this and the clk_fsm and the second - // which resets the rest of the design. - // Or we can make this clock divider not depend on reset. - - flop #(1) pulseReset - (.d(i_RST), - .q(resetD), - .clk(i_CLK)); - - flop #(1) pulseReset2 - (.d(resetD), - .q(resetDD), - .clk(i_CLK)); - - //assign resetPulse = i_RST & ~resetDD; - assign resetPulse = ~i_RST & resetDD; - - assign rstdd2 = i_RST | resetDD; - - flop #(1) fallingEdge - (.d(rstdd2), - .q(rstddn), - .clk(~i_CLK)); - - flopenr #(1) toggle_flip_flop - (.d(w_fd_D), - .q(r_fd_Q), - .clk(i_CLK), - .reset(resetPulse), - .en(w_counter_overflowed)); // only update when counter overflows - - assign w_fd_D = ~ r_fd_Q; - -/* -----\/----- EXCLUDED -----\/----- - if(`FPGA) BUFGMUX clkMux(.I1(r_fd_Q), .I0(i_CLK), .S(i_EN), .O(o_CLK)); - else assign o_CLK = i_EN ? r_fd_Q : i_CLK; - -----/\----- EXCLUDED -----/\----- */ - - if(`FPGA) BUFGMUX clkMux(.I1(r_fd_Q), .I0(i_CLK), .S(i_EN & ~rstddn), .O(o_CLK)); - else assign o_CLK = i_EN & ~rstddn ? r_fd_Q : i_CLK; -endmodule diff --git a/pipelined/src/uncore/sdc/crc16_sipo_np_ce.sv b/pipelined/src/uncore/sdc/crc16_sipo_np_ce.sv deleted file mode 100644 index ae3ce2af9..000000000 --- a/pipelined/src/uncore/sdc/crc16_sipo_np_ce.sv +++ /dev/null @@ -1,63 +0,0 @@ -/////////////////////////////////////////// -// crc16 sipo np ce -// -// Written: Richard Davis -// Modified: Ross Thompson September 18, 2021 -// Converted to system verilog. -// -// Purpose: CRC16 generator SIPO using register_ce -// w/o appending any zero-bits to the message -// -// A component of the CORE-V-WALLY configurable RISC-V project. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - -`include "wally-config.vh" - -module crc16_sipo_np_ce( - input logic CLK, // sequential device - input logic RST, // initial calue of CRC register must be "0000_0000_0000_0000" - input logic i_enable, // input is valid - input logic i_message_bit, - output logic [15:0] o_crc16 -); - - logic [15:0] w_crc16_d; - - flopenr #(16) crc16reg(.clk(CLK), - .reset(RST), - .en(i_enable), - .d(w_crc16_d), - .q(o_crc16)); - - assign w_crc16_d[15] = o_crc16[14]; - assign w_crc16_d[14] = o_crc16[13]; - assign w_crc16_d[13] = o_crc16[12]; - assign w_crc16_d[12] = o_crc16[11] ^ (i_message_bit ^ o_crc16[15]); - assign w_crc16_d[11] = o_crc16[10]; - assign w_crc16_d[10] = o_crc16[9]; - assign w_crc16_d[9] = o_crc16[8]; - assign w_crc16_d[8] = o_crc16[7]; - assign w_crc16_d[7] = o_crc16[6]; - assign w_crc16_d[6] = o_crc16[5]; - assign w_crc16_d[5] = o_crc16[4] ^ (i_message_bit ^ o_crc16[15]); - assign w_crc16_d[4] = o_crc16[3]; - assign w_crc16_d[3] = o_crc16[2]; - assign w_crc16_d[2] = o_crc16[1]; - assign w_crc16_d[1] = o_crc16[0]; - assign w_crc16_d[0] = i_message_bit ^ o_crc16[15]; - - -endmodule diff --git a/pipelined/src/uncore/sdc/crc7_pipo.sv b/pipelined/src/uncore/sdc/crc7_pipo.sv deleted file mode 100644 index 9144495f4..000000000 --- a/pipelined/src/uncore/sdc/crc7_pipo.sv +++ /dev/null @@ -1,67 +0,0 @@ -/////////////////////////////////////////// -// crc7 sipo np ce -// -// Written: Richard Davis -// Modified: Ross Thompson September 18, 2021 -// Converted to system verilog. -// -// Purpose: takes 40 bits of input, generates 7 bit CRC after a single -// clock cycle! -// w/o appending any zero-bits to the message -// -// A component of the CORE-V-WALLY configurable RISC-V project. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - -`include "wally-config.vh" - -module crc7_pipo ( - input logic [39:0] i_DATA, - input logic i_CRC_ENABLE, - input logic RST, - input logic CLK, - output logic [6:0] o_CRC -); - - logic [6:0] r_lfsr_q; - logic [6:0] w_lfsr_d; - - assign o_CRC = r_lfsr_q; - - assign w_lfsr_d[0] = r_lfsr_q[1] ^ r_lfsr_q[2] ^ r_lfsr_q[4] ^ r_lfsr_q[6] ^ i_DATA[0] ^ i_DATA[4] ^ i_DATA[7] ^ i_DATA[8] ^ i_DATA[12] ^ i_DATA[14] ^ i_DATA[15] ^ i_DATA[16] ^ i_DATA[18] ^ i_DATA[20] ^ i_DATA[21] ^ i_DATA[23] ^ i_DATA[24] ^ i_DATA[30] ^ i_DATA[31] ^ i_DATA[34] ^ i_DATA[35] ^ i_DATA[37] ^ i_DATA[39]; - - assign w_lfsr_d[1] = r_lfsr_q[2] ^ r_lfsr_q[3] ^ r_lfsr_q[5] ^ i_DATA[1] ^ i_DATA[5] ^ i_DATA[8] ^ i_DATA[9] ^ i_DATA[13] ^ i_DATA[15] ^ i_DATA[16] ^ i_DATA[17] ^ i_DATA[19] ^ i_DATA[21] ^ i_DATA[22] ^ i_DATA[24] ^ i_DATA[25] ^ i_DATA[31] ^ i_DATA[32] ^ i_DATA[35] ^ i_DATA[36] ^ i_DATA[38]; - - assign w_lfsr_d[2] = r_lfsr_q[0] ^ r_lfsr_q[3] ^ r_lfsr_q[4] ^ r_lfsr_q[6] ^ i_DATA[2] ^ i_DATA[6] ^ i_DATA[9] ^ i_DATA[10] ^ i_DATA[14] ^ i_DATA[16] ^ i_DATA[17] ^ i_DATA[18] ^ i_DATA[20] ^ i_DATA[22] ^ i_DATA[23] ^ i_DATA[25] ^ i_DATA[26] ^ i_DATA[32] ^ i_DATA[33] ^ i_DATA[36] ^ i_DATA[37] ^ i_DATA[39]; - - assign w_lfsr_d[3] = r_lfsr_q[0] ^ r_lfsr_q[2] ^ r_lfsr_q[5] ^ r_lfsr_q[6] ^ i_DATA[0] ^ i_DATA[3] ^ i_DATA[4] ^ i_DATA[8] ^ i_DATA[10] ^ i_DATA[11] ^ i_DATA[12] ^ i_DATA[14] ^ i_DATA[16] ^ i_DATA[17] ^ i_DATA[19] ^ i_DATA[20] ^ i_DATA[26] ^ i_DATA[27] ^ i_DATA[30] ^ i_DATA[31] ^ i_DATA[33] ^ i_DATA[35] ^ i_DATA[38] ^ i_DATA[39]; - - assign w_lfsr_d[4] = r_lfsr_q[1] ^ r_lfsr_q[3] ^ r_lfsr_q[6] ^ i_DATA[1] ^ i_DATA[4] ^ i_DATA[5] ^ i_DATA[9] ^ i_DATA[11] ^ i_DATA[12] ^ i_DATA[13] ^ i_DATA[15] ^ i_DATA[17] ^ i_DATA[18] ^ i_DATA[20] ^ i_DATA[21] ^ i_DATA[27] ^ i_DATA[28] ^ i_DATA[31] ^ i_DATA[32] ^ i_DATA[34] ^ i_DATA[36] ^ i_DATA[39]; - - assign w_lfsr_d[5] = r_lfsr_q[0] ^ r_lfsr_q[2] ^ r_lfsr_q[4] ^ i_DATA[2] ^ i_DATA[5] ^ i_DATA[6] ^ i_DATA[10] ^ i_DATA[12] ^ i_DATA[13] ^ i_DATA[14] ^ i_DATA[16] ^ i_DATA[18] ^ i_DATA[19] ^ i_DATA[21] ^ i_DATA[22] ^ i_DATA[28] ^ i_DATA[29] ^ i_DATA[32] ^ i_DATA[33] ^ i_DATA[35] ^ i_DATA[37]; - - assign w_lfsr_d[6] = r_lfsr_q[0] ^ r_lfsr_q[1] ^ r_lfsr_q[3] ^ r_lfsr_q[5] ^ i_DATA[3] ^ i_DATA[6] ^ i_DATA[7] ^ i_DATA[11] ^ i_DATA[13] ^ i_DATA[14] ^ i_DATA[15] ^ i_DATA[17] ^ i_DATA[19] ^ i_DATA[20] ^ i_DATA[22] ^ i_DATA[23] ^ i_DATA[29] ^ i_DATA[30] ^ i_DATA[33] ^ i_DATA[34] ^ i_DATA[36] ^ i_DATA[38]; - - - - flopenr #(7) - lfsrReg(.clk(CLK), - .reset(RST), - .en(i_CRC_ENABLE), - .d(w_lfsr_d), - .q(r_lfsr_q)); - - -endmodule diff --git a/pipelined/src/uncore/sdc/crc7_sipo_np_ce.sv b/pipelined/src/uncore/sdc/crc7_sipo_np_ce.sv deleted file mode 100644 index 4ada97afa..000000000 --- a/pipelined/src/uncore/sdc/crc7_sipo_np_ce.sv +++ /dev/null @@ -1,60 +0,0 @@ -/////////////////////////////////////////// -// crc16 sipo np ce -// -// Written: Richard Davis -// Modified: Ross Thompson September 18, 2021 -// -// Purpose: CRC7 generator SIPO using register_ce -// w/o appending any zero-bits othe message -// -// A component of the CORE-V-WALLY configurable RISC-V project. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - -`include "wally-config.vh" - -module crc7_sipo_np_ce( - input logic clk, - input logic rst,// initial CRC value must be b"000_0000" - input logic i_enable, - input logic i_message_bit, - output logic [6:0] o_crc7 -); - - - logic [6:0] w_crc7_d; - logic [6:0] r_crc7_q; - - flopenr #(7) - crc7Reg(.clk(clk), - .reset(rst), - .en(i_enable), - .d(w_crc7_d), - .q(r_crc7_q)); - - assign w_crc7_d[6] = r_crc7_q[5]; - assign w_crc7_d[5] = r_crc7_q[4]; - assign w_crc7_d[4] = r_crc7_q[3]; - assign w_crc7_d[3] = r_crc7_q[2] ^ (i_message_bit ^ r_crc7_q[6]); - assign w_crc7_d[2] = r_crc7_q[1]; - assign w_crc7_d[1] = r_crc7_q[0]; - assign w_crc7_d[0] = i_message_bit ^ r_crc7_q[6]; - - assign o_crc7 = r_crc7_q; - - -endmodule - - diff --git a/pipelined/src/uncore/sdc/piso_generic_ce.sv b/pipelined/src/uncore/sdc/piso_generic_ce.sv deleted file mode 100644 index 697dfa864..000000000 --- a/pipelined/src/uncore/sdc/piso_generic_ce.sv +++ /dev/null @@ -1,49 +0,0 @@ -/////////////////////////////////////////// -// piso generic ce -// -// Written: Richard Davis -// Modified: Ross Thompson September 18, 2021 -// -// -// A component of the CORE-V-WALLY configurable RISC-V project. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - -`include "wally-config.vh" - -module piso_generic_ce #(parameter integer g_BUS_WIDTH) ( - input logic clk, - input logic i_load, - input logic [g_BUS_WIDTH-1:0] i_data, - input logic i_en, - output o_data); - - - logic [g_BUS_WIDTH-1:0] w_reg_d; - logic [g_BUS_WIDTH-1:0] r_reg_q; - - flopenr #(g_BUS_WIDTH) - shiftReg(.clk(clk), - .reset(1'b0), - .en(1'b1), - .d(w_reg_d), - .q(r_reg_q)); - - assign o_data = i_en ? r_reg_q[g_BUS_WIDTH - 1] : 1'b1; - assign w_reg_d = i_load ? i_data : - i_en ? {r_reg_q[g_BUS_WIDTH - 2 : 0], 1'b1} : - r_reg_q[g_BUS_WIDTH - 1 : 0]; - -endmodule diff --git a/pipelined/src/uncore/sdc/regfile_p2r1w1_nibo.sv b/pipelined/src/uncore/sdc/regfile_p2r1w1_nibo.sv deleted file mode 100644 index 9ee46b4b6..000000000 --- a/pipelined/src/uncore/sdc/regfile_p2r1w1_nibo.sv +++ /dev/null @@ -1,49 +0,0 @@ -/////////////////////////////////////////// -// regfile_p2r1w1_nibo -// -// Written: Ross Thompson September 18, 2021 -// Modified: 2 port register file with 1 read and 1 write -// -// -// A component of the CORE-V-WALLY configurable RISC-V project. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - -`include "wally-config.vh" - -module regfile_p2r1w1_nibo #(parameter integer DEPTH = 10, parameter integer WIDTH = 4) ( - input logic clk, - input logic we1, - input logic [DEPTH-1:0] ra1, - output logic [WIDTH-1:0] rd1, - output logic [(2**DEPTH)*WIDTH-1:0] Rd1All, - input logic [DEPTH-1:0] wa1, - input logic [WIDTH-1:0] wd1 -); - - logic [WIDTH-1:0] regs [2**DEPTH-1:0]; - genvar index; - - always_ff @(posedge clk) begin - if(we1) begin - regs[wa1] <= wd1; - end - end - - assign rd1 = regs[ra1]; - for(index = 0; index < 2**DEPTH; index++) - assign Rd1All[index*WIDTH+WIDTH-1:index*WIDTH] = regs[index]; - -endmodule diff --git a/pipelined/src/uncore/sdc/regfile_p2r1w1bwen.sv b/pipelined/src/uncore/sdc/regfile_p2r1w1bwen.sv deleted file mode 100644 index cff149e60..000000000 --- a/pipelined/src/uncore/sdc/regfile_p2r1w1bwen.sv +++ /dev/null @@ -1,44 +0,0 @@ -/////////////////////////////////////////// -// regfile_p2r1w1bwen -// -// Written: Ross Thompson September 18, 2021 -// Modified: 2 port register file with 1 read and 1 write -// -// -// A component of the CORE-V-WALLY configurable RISC-V project. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - -`include "wally-config.vh" - -module regfile_p2r1w1bwen #(parameter integer DEPTH = 10, parameter integer WIDTH = 4)( - input logic clk, - input logic we1, - input logic [WIDTH-1:0] we1bit, - input logic [DEPTH-1:0] ra1, - output logic [WIDTH-1:0] rd1, - input logic [DEPTH-1:0] wa1, - input logic [WIDTH-1:0] wd1 -); - - logic [WIDTH-1:0] regs [2**DEPTH-1:0]; - integer i; - - always_ff @(posedge clk) - if (we1) // global write enable - regs[wa1] = wd1 & we1bit | regs[wa1] & ~we1bit; // bit write enable - - assign rd1 = regs[ra1]; -endmodule diff --git a/pipelined/src/uncore/sdc/sd_clk_fsm.sv b/pipelined/src/uncore/sdc/sd_clk_fsm.sv deleted file mode 100644 index 5c47e04f7..000000000 --- a/pipelined/src/uncore/sdc/sd_clk_fsm.sv +++ /dev/null @@ -1,93 +0,0 @@ -/////////////////////////////////////////// -// sd_clk_fsm.sv -// -// Written: Richard Davis -// Modified: Ross Thompson September 19, 2021 -// -// Purpose: Controls clock dividers. -// Replaces s_disable_sd_clocks, s_select_hs_clk, s_enable_hs_clk -// in sd_cmd_fsm.vhd. Attempts to correct issues with oversampling and -// under-sampling of control signals (for counter_cmd), that were present in my -// previous design. -// This runs on 50 MHz. -// sd_cmd_fsm will run on SD_CLK_Gated (50 MHz or 400 KHz, selected by this) -// asynchronous reset is used for both sd_cmd_fsm and for this. -// It must be synchronized with 50 MHz and held for a minimum period of a full -// 400 KHz pulse width. -// -// A component of the CORE-V-WALLY configurable RISC-V project. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - -`include "wally-config.vh" - -module sd_clk_fsm ( - input logic CLK, - input logic i_RST, - (* mark_debug = "true" *)output logic o_DONE, - (* mark_debug = "true" *)input logic i_START, - (* mark_debug = "true" *)input logic i_FATAL_ERROR, - (* mark_debug = "true" *)output logic o_HS_TO_INIT_CLK_DIVIDER_RST, // resets clock divider that is going from 50 MHz to 400 KHz - (* mark_debug = "true" *)output logic o_SD_CLK_SELECTED, // which clock is selected ('0'=HS or '1'=init) - (* mark_debug = "true" *)output logic o_G_CLK_SD_EN // Turns gated clock (G_CLK_SD) off and on -); - - - logic [3:0] w_next_state; - (* mark_debug = "true" *) logic [3:0] r_curr_state; - - - // clock selection - parameter c_sd_clk_init = 1'b1; - parameter c_sd_clk_hs = 1'b0; - - // States - localparam s_reset = 4'b0000; - localparam s_enable_init_clk = 4'b0001; // enable 400 KHz - localparam s_disable_sd_clocks = 4'b0010; - localparam s_select_hs_clk = 4'b0011; - localparam s_enable_hs_clk = 4'b0100; - localparam s_done = 4'b0101; - localparam s_disable_sd_clocks_2 = 4'b0110; // if error occurs - localparam s_select_init_clk = 4'b0111; // if error occurs - localparam s_safe_state = 4'b1111; //always provide a safe state return if all states are not used - - flopenr #(4) stateReg(.clk(CLK), - .reset(i_RST), - .en(1'b1), - .d(w_next_state), - .q(r_curr_state)); - - assign w_next_state = i_RST ? s_reset : - r_curr_state == s_reset | (r_curr_state == s_enable_init_clk & ~i_START) | (r_curr_state == s_select_init_clk) ? s_enable_init_clk : - r_curr_state == s_enable_init_clk & i_START ? s_disable_sd_clocks : - r_curr_state == s_disable_sd_clocks ? s_select_hs_clk : - r_curr_state == s_select_hs_clk ? s_enable_hs_clk : - r_curr_state == s_enable_hs_clk | (r_curr_state == s_done & ~i_FATAL_ERROR) ? s_done : - r_curr_state == s_done & i_FATAL_ERROR ? s_disable_sd_clocks_2 : - r_curr_state == s_disable_sd_clocks_2 ? s_select_init_clk : - s_safe_state; - - - assign o_HS_TO_INIT_CLK_DIVIDER_RST = r_curr_state == s_reset; - - assign o_SD_CLK_SELECTED = (r_curr_state == s_select_hs_clk) | (r_curr_state == s_enable_hs_clk) | (r_curr_state == s_done) ? c_sd_clk_hs : c_sd_clk_init; - - assign o_G_CLK_SD_EN = (r_curr_state == s_enable_init_clk) | (r_curr_state == s_enable_hs_clk) | (r_curr_state == s_done); - - assign o_DONE = r_curr_state == s_done; - -endmodule - diff --git a/pipelined/src/uncore/sdc/sd_cmd_fsm.sv b/pipelined/src/uncore/sdc/sd_cmd_fsm.sv deleted file mode 100644 index 5c2296657..000000000 --- a/pipelined/src/uncore/sdc/sd_cmd_fsm.sv +++ /dev/null @@ -1,586 +0,0 @@ -/////////////////////////////////////////// -// sd_clk_fsm.sv -// -// Written: Richard Davis -// Modified: Ross Thompson September 19, 2021 -// -// Purpose: Finite state machine for the SD CMD bus -// -// A component of the CORE-V-WALLY configurable RISC-V project. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - -`include "wally-config.vh" - -module sd_cmd_fsm ( - input logic CLK, // HS - //i_SLOWER_CLK : in std_logic; - input logic i_RST, // reset FSM, - // MUST COME OUT OF RESET - // SYNCHRONIZED TO THE 1.2 GHZ CLOCK! - output logic o_TIMER_LOAD, o_TIMER_EN, // Timer - output logic [18:0] o_TIMER_IN, - input logic [18:0] i_TIMER_OUT, - output logic o_COUNTER_LOAD, o_COUNTER_EN, // Counter - output logic [7:0] o_COUNTER_IN, - input logic [7:0] i_COUNTER_OUT, - output logic o_SD_CLK_EN, // Clock Gaters - input logic i_CLOCK_CHANGE_DONE, // Communication with CLK_FSM - output logic o_START_CLOCK_CHANGE, // Communication with CLK_FSM - output logic o_IC_RST, o_IC_EN, o_IC_UP_DOWN, // Instruction counter - input logic [3:0] i_IC_OUT, // stop when you get to 10 because that is CMD17 - input logic [1:0] i_USES_DAT, - input logic [6:0] i_OPCODE, - input logic [2:0] i_R_TYPE, - // bit masks - input logic [31:0] i_NO_REDO_MASK, - input logic [31:0] i_NO_REDO_ANS, - input logic [31:0] i_NO_ERROR_MASK, - input logic [31:0] i_NO_ERROR_ANS, - (* mark_debug = "true" *) output logic o_SD_CMD_OE, // Enable ouptut on tri-state SD_CMD line - // TX Components - output logic o_TX_PISO40_LOAD, o_TX_PISO40_EN, // Shift register for TX command head - output logic o_TX_PISO8_LOAD, o_TX_PISO8_EN, // Shift register for TX command tail - output logic o_TX_CRC7_PIPO_RST, o_TX_CRC7_PIPO_EN, // Parallel-to-Parallel CRC7 Generator - output logic [1:0] o_TX_SOURCE_SELECT, // What gets sent to CMD_TX - // TX Memory - output logic o_CMD_TX_IS_CMD55_RST, - output logic o_CMD_TX_IS_CMD55_EN, // '1' means that the command that was just sent has index - // 55, so the subsequent command is to be - // viewed as ACMD by the SD card. - // RX Components - input logic i_SD_CMD_RX, // serial response input on SD_CMD - output logic o_RX_SIPO48_RST, o_RX_SIPO48_EN, // Shift Register for all 48 bits of Response - input logic [39:8] i_RESPONSE_CONTENT, // last 32 bits of RX_SIPO_40_OUT - input logic [45:40] i_RESPONSE_INDEX, // 6 bits from RX_SIPO_40_OUT - output logic o_RX_CRC7_SIPO_RST, o_RX_CRC7_SIPO_EN, // Serial-to-parallel CRC7 Generator - input logic [6:0] i_RX_CRC7, - // RX Memory - output logic o_RCA_REGISTER_RST, o_RCA_REGISTER_EN, // Relative Card Address - // Communication to sd_dat_fsm - output logic o_CMD_TX_DONE, // begin waiting for DAT_RX to complete - input logic i_DAT_RX_DONE, // now go to next state since data block rx was completed - (* mark_debug = "true" *) input logic i_ERROR_CRC16, // repeat last command - (* mark_debug = "true" *) input logic i_ERROR_DAT_TIMES_OUT, - // Commnuication to core - output logic o_READY_FOR_READ, // tell core that I have completed initialization - output logic o_SD_RESTARTING, // inform core the need to restart - input logic i_READ_REQUEST, // core tells me to execute CMD17 - // Communication to Host - output logic o_DAT_ERROR_FD_RST, - output logic [2:0] o_ERROR_CODE_Q, // Indicates what caused the fatal error - output logic o_FATAL_ERROR, // SD Card is damaged beyond recovery, restart entire initialization procedure of card - input logic LIMIT_SD_TIMERS -); - - logic [4:0] w_next_state; - (* mark_debug = "true" *) logic [4:0] r_curr_state; - logic w_resend_last_command, w_rx_crc7_check, w_rx_index_check, w_rx_bad_crc7, w_rx_bad_index, w_rx_bad_reply, w_bad_card; - - logic [31:0] w_redo_result, w_error_result; - logic w_ACMD41_init_done; - logic w_fail_cnt_en, w_fail_count_rst; - logic [10:0] r_fail_count_out; - - logic w_ACMD41_busy_timer_START, w_ACMD41_times_out_FLAG, w_ACMD41_busy_timer_RST; //give up after 1000 ms of ACMD41 - logic [2:0] w_ERROR_CODE_D, r_ERROR_CODE_Q ; // Error Codes for fatal error on SD CMD FSM - logic w_ERROR_CODE_RST, w_ERROR_CODE_EN; - logic [18:0] Timer_In; - - - localparam s_reset_clear_error_reg = 5'b00000; - localparam s_idle_supply_no_clk = 5'b00001; - localparam s_idle_supply_sd_clk = 5'b00010; - localparam s_ld_head = 5'b00011; - localparam s_tx_head = 5'b00100; - localparam s_ld_tail = 5'b00101; - localparam s_tx_tail = 5'b00110; - localparam s_setup_rx = 5'b00111; - localparam s_idle_ncc = 5'b01000; - localparam s_fetch_next_cmd = 5'b01001; - localparam s_rx_48 = 5'b01010; - localparam s_rx_136 = 5'b01011; - localparam s_error_no_response = 5'b01100; - localparam s_idle_for_dat = 5'b01101; - localparam s_error_bad_card = 5'b01110; - localparam s_idle_nrc = 5'b01111; - localparam s_count_attempt = 5'b10000; - localparam s_reset_from_error = 5'b10001; - //localparam s_enable_hs_clk = 5'b10010; - localparam s_idle_for_start_bit = 5'b10011; - localparam s_fetch_prev_cmd = 5'b10100; // use to resend previous cmd55 if acmd is resent - // localparam s_setup_rx_b = 5'b10110; -// localparam s_idle_for_start_bit_b= 5'b10111; -// localparam s_rx_48_b = 5'b11000; -// localparam s_rx_136_b = 5'b11001; - localparam s_error_dat_time_out = 5'b11010; // don't advance states if the dat fsm times out - localparam s_idle_for_clock_change = 5'b11011; // replaces s_disable_sd_clocks, s_select_hs_clk, s_enable_hs_clk - localparam s_study_response = 5'b11100; // Do error checking here - localparam s_idle_for_read_request = 5'b11101; // After power up and initialization sequence is completed - localparam s_Error_TX_Failed = 5'b11110; // when fail_cnt_out exceeds c_max_attempts - - localparam c_MAX_ATTEMPTS = 1500; // Give up sending a command after 3 failed attempts - // (except ACMD41) so the processor is not locked up forever - - localparam c_response_type_R0_NONE = 0; - localparam c_response_type_R1_NORMAL = 1; - localparam c_response_type_R2_CID_CSD = 2; - localparam c_response_type_R3_OCR = 3; - localparam c_response_type_R6_RCA = 6; - localparam c_response_type_R7_CIC = 7; - - localparam c_start_bit = 1'b0; - - localparam c_DAT_none = 2'b00; - localparam c_DAT_busy = 2'b01; - localparam c_DAT_wide = 2'b10; - localparam c_DAT_block = 2'b11; - - // Instructions mnemonics based on index (opcode(5 downto 0)) - localparam logic [45:40] c_Go_Idle_State = 6'd0; //CMD0 - localparam logic [45:40] c_All_Send_CID = 6'd02; // CMD2 - localparam logic [45:40] c_SD_Send_RCA = 6'd03; // CMD3 - localparam logic [45:40] c_Switch_Function = 6'd06; // CMD6 - localparam logic [45:40] c_Set_Bus_Width = 6'd06; // ACMD6 - localparam logic [45:40] c_Select_Card = 6'd07; // CMD7 - localparam logic [45:40] c_Send_IF_State = 6'd08; // CMD8 - localparam logic [45:40] c_Read_Single_Block = 6'd17; // CMD17 - localparam logic [45:40] c_SD_Send_OCR = 6'd41; // ACMD41 - localparam logic [45:40] c_App_Command = 6'd55; // CMD55 - -// clock selection - localparam c_sd_clk_init = 1'b1; - localparam c_sd_clk_hs = 1'b0; - - //tx source selection - localparam logic [1:0] c_tx_low = 2'b00; - localparam logic [1:0] c_tx_high = 2'b01; - localparam logic [1:0] c_tx_head = 2'b10; - localparam logic [1:0] c_tx_tail = 2'b11; - - // Error Codes for Error Register - localparam logic [2:0] c_NO_ERRORS = 3'b000; // no fatal errors occurred - // (default value when register is cleared during reset) - localparam [2:0] C_ERROR_NO_CMD_RESPONSE = 3'b100; // card timed out while waiting for a response on CMD, no start bit - // of response packet was ever received - // (possible causes: illegal command, card is disconnected, - // not meeting timing (you can fix timing by inverting the clock - // sent to card)) - localparam logic [2:0] c_ERROR_NO_DAT_RESPONSE = 3'b101; // card timed out while waiting for a data block on DAT, no start bit - // of DAT packet was ever received - // (possible cause: card is disconnected) - localparam logic [2:0] C_ERROR_BAD_CARD_STATUS = 3'b110; // status bits of a response indicate a card is not supported - // or that the card is damaged internally - localparam logic [2:0] C_ERROR_EXCEED_MAX_ATTEMPTS = 3'b111; // if a command fails it may be resent, - // but after so many attempts you should just give up - - //Alias for value of SD_CMD_Output_Enable - localparam c_TX_COMMAND = 1'b1; // Enable output on SD_CMD - localparam c_RX_RESPONSE = 1'b0; // Disable Output on SD_CMD - - // load values in for timers and counters - localparam logic [7:0] c_NID_max = 8'd63; // counter_in: should be "4" - // downto 0 = 5 bits count - // but is not enough time for - // sdModel.v - localparam logic [7:0] c_NCR_max = 8'd63; // counter_in - localparam logic [7:0] c_NCC_min = 8'd7; // counter_in - localparam logic [7:0] c_NRC_min = 8'd8; // counter_in - - //localparam logic [18:0] c_1000ms = 19'd400000; // ACMD41 timeout - //*** BUG this value is too bit to fit into 19 bits. - localparam logic [18:0] c_1000ms = 19'd40000; // ACMD41 timeout - - // command instruction type (opcode(6)) - localparam c_CMD = 1'b0; - localparam c_ACMD = 1'b1; - - // counter direction for up_down - localparam c_increment = 1'b1; // count <= count + 1 - localparam c_decrement = 1'b0; // count <= count - 1 - - - logic COUNTER_OUT_GT_ZERO; - logic COUNTER_OUT_GE_ZERO; - logic COUNTER_OUT_GT_8; - logic COUNTER_OUT_EQ_8; - logic COUNTER_OUT_EQ_ZERO; - logic TIMER_OUT_GT_ZERO; - logic TIMER_OUT_EQ_ZERO; - logic fail_count_out_le_max_attempts; - logic fail_count_out_lt_max_attempts; - logic fail_count_out_gt_max_attempts; - logic IC_OUT_EQ_2; - logic IC_OUT_EQ_3; - logic IC_OUT_LT_9; - logic IC_OUT_GE_9; - - - assign Timer_In = LIMIT_SD_TIMERS ? 19'b0000000000000000011 : 19'b0011000011010100000; // 250 ms - - //Fail Counter, tracks how many failed attempts at command transmission - SDCcounter #(11) fail_counter - (.CountIn(11'b0), - .CountOut(r_fail_count_out), - .Load(1'b0), - .Enable(w_fail_cnt_en), - .clk(CLK), - .reset(w_fail_count_rst)); - - // Simple timer for ACMD41 busy - simple_timer #(19) ACMD41_busy_timer - (.VALUE(c_1000ms), - .START(w_ACMD41_busy_timer_START), - .FLAG(w_ACMD41_times_out_FLAG), - .RST(w_ACMD41_busy_timer_RST), - .CLK(CLK)); - - // State Register, instantiate register_ce. 32 state state machine - flopenr #(5) state_reg - (.d(w_next_state), - .q(r_curr_state), - .en(1'b1), - .reset(i_RST), - .clk(CLK)); - - // Error register : indicates what type of fatal error occured for interrupt - flopenr #(3) error_reg - (.d(w_ERROR_CODE_D), - .q(r_ERROR_CODE_Q), - .en(w_ERROR_CODE_EN), - .reset(w_ERROR_CODE_RST), - .clk(CLK)); - - assign o_ERROR_CODE_Q = r_ERROR_CODE_Q; - assign COUNTER_OUT_GT_ZERO = i_COUNTER_OUT > 0; - assign COUNTER_OUT_GE_ZERO = $signed(i_COUNTER_OUT) >= $signed(8'b0); - assign COUNTER_OUT_GT_8 = i_COUNTER_OUT > 8; - assign COUNTER_OUT_EQ_8 = i_COUNTER_OUT == 8; - assign COUNTER_OUT_EQ_ZERO = i_COUNTER_OUT == 0; - assign TIMER_OUT_GT_ZERO = i_TIMER_OUT > 0; - assign TIMER_OUT_EQ_ZERO = i_TIMER_OUT == 0; - assign fail_count_out_le_max_attempts = r_fail_count_out <= (c_MAX_ATTEMPTS-1); - assign fail_count_out_lt_max_attempts = r_fail_count_out < (c_MAX_ATTEMPTS-1); - assign fail_count_out_gt_max_attempts = r_fail_count_out > (c_MAX_ATTEMPTS-1); - assign IC_OUT_EQ_2 = i_IC_OUT == 2; - assign IC_OUT_EQ_3 = i_IC_OUT == 3; - assign IC_OUT_LT_9 = i_IC_OUT < 9; - assign IC_OUT_GE_9 = i_IC_OUT >= 9; - - assign w_next_state = i_RST ? s_reset_clear_error_reg : - - ((r_curr_state == s_reset_clear_error_reg) | - (r_curr_state == s_Error_TX_Failed) | - (r_curr_state == s_error_no_response) | - (r_curr_state == s_error_bad_card) | - (r_curr_state == s_error_dat_time_out)) ? s_reset_from_error : - - - ((r_curr_state == s_reset_from_error) | - ((r_curr_state == s_idle_supply_no_clk) & (TIMER_OUT_GT_ZERO))) ? s_idle_supply_no_clk : - - (((r_curr_state == s_idle_supply_no_clk) & (TIMER_OUT_EQ_ZERO)) | - ((r_curr_state == s_idle_supply_sd_clk) & (COUNTER_OUT_GT_ZERO))) ? s_idle_supply_sd_clk : - - (r_curr_state == s_ld_head) ? s_count_attempt : - - (((r_curr_state == s_count_attempt) & (fail_count_out_le_max_attempts)) | - ((r_curr_state == s_count_attempt) & - (((IC_OUT_EQ_2) & (i_OPCODE[5:0] == c_App_Command)) | - ((IC_OUT_EQ_3) & (i_OPCODE == ({c_ACMD, c_SD_Send_OCR})))) // to work CMD55, ACMD41 MUST be lines 2, 3 of instruction fetch mux of sd_top.vhd - & (w_ACMD41_times_out_FLAG) - & (fail_count_out_gt_max_attempts))) ? s_tx_head : - - ((r_curr_state == s_count_attempt) & (fail_count_out_gt_max_attempts)) ? s_Error_TX_Failed : - - ((r_curr_state == s_tx_head) | ((r_curr_state == s_ld_tail) & (COUNTER_OUT_GT_8))) ? s_ld_tail : - - (((r_curr_state == s_ld_tail) & (COUNTER_OUT_EQ_8)) | - ((r_curr_state == s_tx_tail) & (COUNTER_OUT_GT_ZERO))) ? s_tx_tail : - - (r_curr_state == s_tx_tail) & (COUNTER_OUT_EQ_ZERO) ? s_setup_rx : - - (((r_curr_state == s_setup_rx) & (i_R_TYPE == c_response_type_R0_NONE)) | - ((r_curr_state == s_idle_ncc) & (COUNTER_OUT_GT_ZERO))) ? s_idle_ncc : - - (((r_curr_state == s_setup_rx) & (i_R_TYPE != c_response_type_R0_NONE)) | - ((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX != c_start_bit) & - (COUNTER_OUT_GT_ZERO))) ? s_idle_for_start_bit : - - ((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX != c_start_bit) & - (COUNTER_OUT_EQ_ZERO)) ? s_error_no_response : - - (((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX == c_start_bit) & - /* verilator lint_off UNSIGNED */ - (COUNTER_OUT_GE_ZERO) & (i_R_TYPE == c_response_type_R2_CID_CSD)) | - /* verilator lint_on UNSIGNED */ - ((r_curr_state == s_rx_136) & (COUNTER_OUT_GT_ZERO))) ? s_rx_136 : - - (((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX == c_start_bit) & - /* verilator lint_off UNSIGNED */ - (COUNTER_OUT_GE_ZERO) & (i_R_TYPE != c_response_type_R2_CID_CSD)) | - /* verilator lint_on UNSIGNED */ - ((r_curr_state == s_rx_48) & (COUNTER_OUT_GT_ZERO))) ? s_rx_48 : - - (((r_curr_state == s_rx_136) & (COUNTER_OUT_EQ_ZERO)) | - ((r_curr_state == s_rx_48) & COUNTER_OUT_EQ_ZERO)) ? s_study_response : - - (r_curr_state == s_study_response) & w_bad_card ? s_error_bad_card : - - (((r_curr_state == s_study_response) & (~w_bad_card) & (i_USES_DAT != c_DAT_none)) | - ((r_curr_state == s_idle_for_dat) & (~i_DAT_RX_DONE))) ? s_idle_for_dat : - - ((r_curr_state == s_idle_for_dat) & (i_DAT_RX_DONE) & (i_ERROR_DAT_TIMES_OUT)) ? s_error_dat_time_out : - - (((r_curr_state == s_idle_for_dat) & (i_DAT_RX_DONE) & - (~i_ERROR_DAT_TIMES_OUT)) | - ((r_curr_state == s_study_response) & (~w_bad_card) & - (i_USES_DAT == c_DAT_none)) | - ((r_curr_state == s_idle_nrc) & (COUNTER_OUT_GT_ZERO))) ? s_idle_nrc : - - ((r_curr_state == s_idle_nrc) & (COUNTER_OUT_EQ_ZERO) & - (w_resend_last_command) & ((i_OPCODE[6] == c_ACMD) & - ((i_OPCODE[5:0]) != c_App_Command))) ? s_fetch_prev_cmd : - - ((r_curr_state == s_fetch_prev_cmd) | - ((r_curr_state == s_idle_supply_sd_clk) & (COUNTER_OUT_EQ_ZERO)) | - ((r_curr_state == s_fetch_next_cmd) & // before CMD17 - (IC_OUT_LT_9)) | // blindly load head of next command - ((r_curr_state == s_idle_for_read_request) & (i_READ_REQUEST)) | // got the request, load head - ((r_curr_state == s_idle_nrc) & (COUNTER_OUT_EQ_ZERO) & - (w_resend_last_command) & ((i_OPCODE[6] == c_CMD) | - ((i_OPCODE[5:0]) == c_App_Command)))) ? s_ld_head : - - (((r_curr_state == s_idle_nrc) & (COUNTER_OUT_EQ_ZERO) & - (~w_resend_last_command) & ((i_OPCODE) == ({c_CMD, c_Switch_Function}))) | - ((r_curr_state == s_idle_for_clock_change) & (~i_CLOCK_CHANGE_DONE))) ? s_idle_for_clock_change : - - (((r_curr_state == s_idle_ncc) & (COUNTER_OUT_EQ_ZERO)) | - ((r_curr_state == s_idle_nrc) & (COUNTER_OUT_EQ_ZERO) & - (~w_resend_last_command) & ((i_OPCODE) != ({c_CMD, c_Switch_Function}))) | - ((r_curr_state == s_idle_for_clock_change) & (i_CLOCK_CHANGE_DONE))) ? s_fetch_next_cmd : - - (((r_curr_state == s_fetch_next_cmd) & - (IC_OUT_GE_9)) | // During and after CMD17, wait for request to send CMD17 from core - // waiting for request - (r_curr_state == s_idle_for_read_request)) ? s_idle_for_read_request : - - s_reset_clear_error_reg; - - - - - - - // state outputs - assign w_ACMD41_busy_timer_START = ((r_curr_state == s_count_attempt) & (i_OPCODE == {c_ACMD, c_SD_Send_OCR}) & (r_fail_count_out == 1)); - - assign w_ACMD41_busy_timer_RST = ((r_curr_state == s_reset_from_error) | (w_ACMD41_init_done)); - - // Error Register - assign w_ERROR_CODE_RST = (r_curr_state == s_reset_clear_error_reg); - - assign w_ERROR_CODE_EN = (r_curr_state == s_error_bad_card) | (r_curr_state == s_error_no_response) | (r_curr_state == s_Error_TX_Failed) | (r_curr_state == s_error_dat_time_out); - - assign w_ERROR_CODE_D = (r_curr_state == s_Error_TX_Failed) ? C_ERROR_EXCEED_MAX_ATTEMPTS : // give up - (r_curr_state == s_error_bad_card) ? C_ERROR_BAD_CARD_STATUS : // card is damaged or unsupported - (r_curr_state == s_error_no_response) ? C_ERROR_NO_CMD_RESPONSE : // no response was received on CMD line - (r_curr_state == s_error_dat_time_out) ? c_ERROR_NO_DAT_RESPONSE : // no data packet was received on DAT bus - c_NO_ERRORS; // all is well - - // Failure counter - assign w_fail_count_rst = ((r_curr_state == s_reset_from_error) | (r_curr_state == s_fetch_next_cmd & i_OPCODE[5:0] != c_App_Command)); - - - assign w_fail_cnt_en = ((r_curr_state == s_count_attempt) & (i_OPCODE[6] != c_ACMD | i_OPCODE[5:0] == c_App_Command)); - // & (i_OPCODE != ({c_ACMD, c_SD_Send_OCR})) else // NOT ACMD41, it can take up to 1 second - - // Timer module - assign o_TIMER_EN = (r_curr_state == s_idle_supply_no_clk); - - assign o_TIMER_LOAD = (r_curr_state == s_reset_from_error); - - assign o_TIMER_IN = (r_curr_state == s_reset_from_error) ? Timer_In : '0; - - // Clock selection/gater module(s) ... - assign o_SD_CLK_EN = ~((r_curr_state == s_reset_from_error) | (r_curr_state == s_idle_supply_no_clk) | (r_curr_state == s_idle_for_clock_change)); - - assign o_START_CLOCK_CHANGE = (r_curr_state == s_idle_for_clock_change); - - // RCA register module - assign o_RCA_REGISTER_RST = (r_curr_state == s_reset_from_error); - - assign o_RCA_REGISTER_EN = ((r_curr_state == s_idle_nrc) & (i_R_TYPE == c_response_type_R6_RCA)); - - // Instruction counter module - assign o_IC_RST = (r_curr_state == s_reset_from_error); - - //assign o_IC_EN = (r_curr_state == s_fetch_next_cmd) | (r_curr_state == s_fetch_prev_cmd); - - assign o_IC_EN = (((r_curr_state == s_fetch_next_cmd) & (i_IC_OUT < 10)) | (r_curr_state == s_fetch_prev_cmd)); - - assign o_IC_UP_DOWN = (r_curr_state == s_fetch_prev_cmd) ? c_decrement : c_increment; - - // "Previous Command sent was CMD55, so the command I'm now sending is ACMD" module - assign o_CMD_TX_IS_CMD55_RST = (r_curr_state == s_reset_from_error); - - assign o_CMD_TX_IS_CMD55_EN = (r_curr_state == s_ld_head); - - // Output signals to DAT FSM - //o_CMD_TX_DONE = '0' when (r_curr_state == s_reset) else // reset - // '0' when (r_curr_state == s_idle_supply_no_clk) | (r_curr_state == s_idle_supply_sd_clk) else // power up - // '0' when ((r_curr_state == s_ld_head) - // | (r_curr_state == s_tx_head) - // | (r_curr_state == s_ld_tail) - // | (r_curr_state == s_tx_tail)) else // tx - // '1'; - assign o_CMD_TX_DONE = (r_curr_state == s_setup_rx); - - // Counter Module - assign o_COUNTER_LOAD = (r_curr_state == s_idle_supply_no_clk) | - (r_curr_state == s_ld_head) | - (r_curr_state == s_setup_rx) | - (r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX == c_start_bit) | - (r_curr_state == s_rx_48) & (i_COUNTER_OUT == 0) | - (r_curr_state == s_rx_136) & (i_COUNTER_OUT == 0); - - assign o_COUNTER_IN = (r_curr_state == s_idle_supply_no_clk) ? 8'd73 : - // | is it 73 downto 0 == 74 bits - (r_curr_state == s_ld_head) ? 8'd47 : // or is it 48 - ((r_curr_state == s_setup_rx) & (i_R_TYPE == c_response_type_R0_NONE)) ? c_NCC_min : - ((r_curr_state == s_setup_rx) - & (i_R_TYPE != c_response_type_R0_NONE) - & (((i_OPCODE) == ({c_CMD, c_All_Send_CID})) | - ((i_OPCODE) == ({c_ACMD, c_SD_Send_OCR})))) ? c_NID_max : - (r_curr_state == s_setup_rx) ? c_NCR_max : - ((r_curr_state == s_idle_for_start_bit) & (i_R_TYPE == c_response_type_R2_CID_CSD)) ? 8'd135 : // | is it 136 - (r_curr_state == s_idle_for_start_bit) ? 8'd46 : // | is it not48 - (r_curr_state == s_rx_48) | (r_curr_state == s_rx_136) ? c_NRC_min : // | is it 8 - 8'd0; - - assign o_COUNTER_EN = (r_curr_state == s_idle_supply_sd_clk) ? 1'b1 : - ((r_curr_state == s_tx_head) | (r_curr_state == s_ld_tail) | (r_curr_state == s_tx_tail)) ? 1'b1 : - (r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX == c_start_bit) ? 1'b0 : - (r_curr_state == s_idle_for_start_bit) ? 1'b1 : - (r_curr_state == s_rx_48) & (i_COUNTER_OUT == 0) ? 1'b0 : - (r_curr_state == s_rx_48) ? 1'b1 : - (r_curr_state == s_idle_nrc) ? 1'b1 : - (r_curr_state == s_rx_136) & (i_COUNTER_OUT == 0) ? 1'b0 : - (r_curr_state == s_rx_136) ? 1'b1 : - (r_curr_state == s_idle_ncc) ? 1'b1 : - 1'b0; - - // SD_CMD Tri-state Buffer Module - assign o_SD_CMD_OE = (r_curr_state == s_idle_supply_sd_clk) ? c_TX_COMMAND : - ((r_curr_state == s_tx_head) - | (r_curr_state == s_ld_tail) - | (r_curr_state == s_tx_tail)) ? c_TX_COMMAND : - c_RX_RESPONSE; - - // Shift Registers - // TX_PISO40 Transmit Command Head - assign o_TX_PISO40_LOAD = (r_curr_state == s_ld_head); - - assign o_TX_PISO40_EN = (r_curr_state == s_tx_head) | (r_curr_state == s_ld_tail); - - // TX_CRC7_PIPO Generate Tail - assign o_TX_CRC7_PIPO_RST = (r_curr_state == s_ld_head); - - assign o_TX_CRC7_PIPO_EN = (r_curr_state == s_tx_head); - - // TX_PISO8 Transmit Command Tail - assign o_TX_PISO8_LOAD = (r_curr_state == s_ld_tail); - - assign o_TX_PISO8_EN = (r_curr_state == s_tx_tail); - - // RX_CRC7_SIPO Calculate the CRC7 of the first 47-bits of reply (should be zero) - assign o_RX_CRC7_SIPO_RST = (r_curr_state == s_setup_rx); - - assign o_RX_CRC7_SIPO_EN = (r_curr_state == s_rx_48) & (i_COUNTER_OUT > 0); // or (r_curr_state == s_rx_48_b) - - // RX_SIPO40 Content bits of response - assign o_RX_SIPO48_RST = (r_curr_state == s_setup_rx); - - assign o_RX_SIPO48_EN = (r_curr_state == s_rx_48 | r_curr_state == s_rx_48); - - // Fatal Error Signal Wire - assign o_FATAL_ERROR = (r_curr_state == s_error_bad_card) | (r_curr_state == s_error_no_response) | - (r_curr_state == s_Error_TX_Failed) | (r_curr_state == s_error_dat_time_out); - - assign o_DAT_ERROR_FD_RST = (r_curr_state == s_ld_head); - - // I'm debating the merit of creating yet another state for sd_cmd_fsm.vhd to go into when and if sd_dat_fsm.vhd - // times out while waiting for start bit on the DAT bus resulting in Error_Time_Out going high in - // sd_Dat_fsm.vhd while sd_cmd_fsm.vhd is still in s_idle_for_dat - - // TX source selection bits for mux - assign o_TX_SOURCE_SELECT = (r_curr_state == s_idle_supply_sd_clk) ? c_tx_high : - ((r_curr_state == s_ld_head) - | (r_curr_state == s_tx_head) - | (r_curr_state == s_ld_tail)) ? c_tx_head : - (r_curr_state == s_tx_tail) ? c_tx_tail : - c_tx_high; // This occurs when not transmitting anything - - // Study Response - assign w_rx_crc7_check = (r_curr_state == s_idle_nrc) & - ((i_R_TYPE != c_response_type_R0_NONE) & - (i_R_TYPE != c_response_type_R3_OCR) & - (i_R_TYPE != c_response_type_R2_CID_CSD)); - - assign w_rx_index_check = (r_curr_state == s_idle_nrc) & - ((i_R_TYPE != c_response_type_R0_NONE) & - (i_R_TYPE != c_response_type_R3_OCR) & - (i_R_TYPE != c_response_type_R2_CID_CSD)); - - assign w_redo_result = i_RESPONSE_CONTENT & i_NO_REDO_MASK; - - assign w_rx_bad_reply = ((r_curr_state == s_idle_nrc | r_curr_state == s_study_response) & (w_redo_result != i_NO_REDO_ANS)); - - assign w_rx_bad_crc7 = ((r_curr_state == s_idle_nrc | r_curr_state == s_study_response) & ((w_rx_crc7_check) & (i_RX_CRC7 != 7'b0))); - - assign w_rx_bad_index = ((r_curr_state == s_idle_nrc | r_curr_state == s_study_response) - & ((w_rx_index_check) & (i_RESPONSE_INDEX != i_OPCODE[5:0]))); - - assign w_resend_last_command = ((r_curr_state == s_idle_nrc | r_curr_state == s_study_response) & - ((w_rx_bad_reply) | (w_rx_bad_index) | (w_rx_bad_crc7))) | - ((r_curr_state == s_idle_nrc) & - ((i_ERROR_CRC16) & - ((i_USES_DAT == c_DAT_block) | (i_USES_DAT == c_DAT_wide)))); - - assign w_error_result = i_RESPONSE_CONTENT & i_NO_ERROR_MASK; - - // Make assignment based on what was read from the OCR Register. - // Bit 31, Card power up status bit: '1' == SD Flash Card power up procedure is finished. - // '0' == SD Flash Card power up procedure is not finished. - // Bit 30, Card capacity status bit: '1' == Extended capacity card is in use (64 GB in size or greater). - // '0' == Extended capacity card is not in use. - assign w_ACMD41_init_done = ((i_IC_OUT == 3) & (i_OPCODE == ({c_ACMD, c_SD_Send_OCR}))) & - (~w_rx_bad_reply) & (r_curr_state == s_study_response); - - assign w_bad_card = ((r_curr_state == s_study_response) & (w_error_result != i_NO_ERROR_ANS) & - ((~w_ACMD41_times_out_FLAG) | (w_ACMD41_init_done))); - - // Communication with core - assign o_READY_FOR_READ = (r_curr_state == s_idle_for_read_request); - - assign o_SD_RESTARTING = (r_curr_state == s_Error_TX_Failed) | - (r_curr_state == s_error_dat_time_out) | - (r_curr_state == s_error_bad_card) | - (r_curr_state == s_error_no_response); - - - - -endmodule diff --git a/pipelined/src/uncore/sdc/sd_dat_fsm.sv b/pipelined/src/uncore/sdc/sd_dat_fsm.sv deleted file mode 100644 index c38073e34..000000000 --- a/pipelined/src/uncore/sdc/sd_dat_fsm.sv +++ /dev/null @@ -1,253 +0,0 @@ -/////////////////////////////////////////// -// sd_dat_fsm.sv -// -// Written: Richard Davis -// Modified: Ross Thompson September 19, 2021 -// -// Purpose: Runs in parallel with sd_cmd_fsm to control activity on the DAT -// bus of the SD card. -// 14 State Mealy FSM + Safe state = 15 State Mealy FSM -// -// A component of the CORE-V-WALLY configurable RISC-V project. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - -`include "wally-config.vh" - -module sd_dat_fsm ( - input logic CLK, // HS Clock (48 MHz) - input logic i_RST, - // Timer module control - input logic i_SD_CLK_SELECTED, // Which frequency I'm in determines what count in to load for a 100ms timer - output logic o_TIMER_LOAD, o_TIMER_EN, // Timer Control signals - output logic [22:0] o_TIMER_IN, // Need Enough bits for 100 milliseconds at 48MHz - input logic [22:0] i_TIMER_OUT, // (ceiling(log((clk freq)(delay desired)-1)/log(2))-1) downto 0 - // Nibble counter module control - output logic o_COUNTER_RST, o_COUNTER_EN, // nibble counter - input logic [10:0] i_COUNTER_OUT, // max nibbles is 1024 + crc16 bits = 1040 bits - // CRC16 Generation control - (* mark_debug = "true" *)output logic o_CRC16_EN, o_CRC16_RST, // shared signals for all 4 CRC16_SIPO (one for each of 4 DAT lines) - (* mark_debug = "true" *)input logic i_DATA_CRC16_GOOD, // indicates that no errors in transmission when CRC16 are all zero - // For R1b - output logic o_BUSY_RST, o_BUSY_EN, // busy signal for R1b - (* mark_debug = "true" *)input logic i_DAT0_Q, - // Storage Buffers for DAT bits read - output logic o_NIBO_EN, // 512 bytes block data (Nibble In Block Out) - // From LUT - (* mark_debug = "true" *)input logic [1:0] i_USES_DAT, // current command needs use of DAT bus - // For communicating with core - output logic o_DATA_VALID, // indicates that DATA being send over o_DATA to core is valid - output logic o_LAST_NIBBLE, // indicates that the last nibble has been sent - // For communication with sd_cmd_fsm - (* mark_debug = "true" *)input logic i_CMD_TX_DONE, // command transmission completed, begin waiting for DATA - (* mark_debug = "true" *)output logic o_DAT_RX_DONE, // tell SD_CMD_FSM that DAT communication is completed, send next instruction to sd card - (* mark_debug = "true" *)output logic o_ERROR_DAT_TIMES_OUT, // error flag for when DAT times out (so don't fetch more instructions) - (* mark_debug = "true" *)output logic o_DAT_ERROR_FD_RST, - (* mark_debug = "true" *)output logic o_DAT_ERROR_FD_EN, // tell SD_CMD_FSM to resend command due to error in transmission - input logic LIMIT_SD_TIMERS -); - - (* mark_debug = "true" *) logic [3:0] r_curr_state; - logic [3:0] w_next_state; - - logic r_error_crc16_fd_Q; - - logic [22:0] Identify_Timer_In; - logic [22:0] Data_TX_Timer_In; - - localparam logic [3:0] s_reset = 4'b0000; - localparam logic [3:0] s_idle = 4'b0001; - localparam logic [3:0] s_idle_for_start_bit = 4'b0010; - localparam logic [3:0] s_read_r1b = 4'b0011; - localparam logic [3:0] s_notify_r1b_completed = 4'b0100; - localparam logic [3:0] s_error_time_out = 4'b0101; - localparam logic [3:0] s_rx_wide_data = 4'b0110; - localparam logic [3:0] s_rx_block_data = 4'b0111; - localparam logic [3:0] s_rx_crc16 = 4'b1000; - localparam logic [3:0] s_error_crc16_fail = 4'b1001; - localparam logic [3:0] s_publish_block_data = 4'b1010; - localparam logic [3:0] s_publish_wide_data = 4'b1011; - localparam logic [3:0] s_reset_wide_data = 4'b1100; - localparam logic [3:0] s_reset_block_data = 4'b1101; - localparam logic [3:0] s_reset_nibble_counter = 4'b1110; // Before publishing CMD17 Block Data - - localparam logic [1:0] c_DAT_none = 2'b00; - localparam logic [1:0] c_DAT_busy = 2'b01; - localparam logic [1:0] c_DAT_wide = 2'b10; - localparam logic [1:0] c_DAT_block = 2'b11; - - localparam logic c_start_bit = 0; - localparam logic c_busy_bit = 0; - - // load values in for timers and counters - localparam logic c_slow_clock = 1'b1; // use during initialization (card identification mode) - localparam logic c_HS_clock = 1'b0; // use after CMD6 switches clock frequency (CMD17) - - - logic TIMER_OUT_GT_0; - logic TIMER_OUT_EQ_0; - logic COUNTER_OUT_EQ_1023; - logic COUNTER_OUT_LT_1023; - logic COUNTER_OUT_LT_128; - logic COUNTER_OUT_EQ_128; - logic COUNTER_OUT_LT_144; - logic COUNTER_OUT_EQ_144; - logic COUNTER_OUT_LT_1040; - logic COUNTER_OUT_EQ_1040; - - - assign Identify_Timer_In = LIMIT_SD_TIMERS ? 23'b00000000000000001100011 : 23'b00000001001110001000000; // 40,000 unsigned. - assign Data_TX_Timer_In = LIMIT_SD_TIMERS ? 23'b00000000000000001100011 : 23'b11110100001001000000000; // 8,000,000 unsigned. - - flopenr #(4) stateReg(.clk(CLK), - .reset(i_RST), - .en(1'b1), - .d(w_next_state), - .q(r_curr_state)); - - assign TIMER_OUT_GT_0 = i_TIMER_OUT > 0; - assign TIMER_OUT_EQ_0 = i_TIMER_OUT == 0; - assign COUNTER_OUT_EQ_1023 = i_COUNTER_OUT == 1023; - assign COUNTER_OUT_LT_1023 = i_COUNTER_OUT < 1023; - assign COUNTER_OUT_LT_128 = i_COUNTER_OUT < 128; - assign COUNTER_OUT_EQ_128 = i_COUNTER_OUT == 128; - assign COUNTER_OUT_LT_144 = i_COUNTER_OUT < 144; - assign COUNTER_OUT_EQ_144 = i_COUNTER_OUT == 144; - assign COUNTER_OUT_LT_1040 = i_COUNTER_OUT < 1040; - assign COUNTER_OUT_EQ_1040 = i_COUNTER_OUT == 1040; - - assign w_next_state = ((i_RST) | - (r_curr_state == s_error_time_out) | // noticed this change is needed during emulation - (r_curr_state == s_notify_r1b_completed) | - (r_curr_state == s_error_crc16_fail) | - (r_curr_state == s_publish_wide_data) | - ((r_curr_state == s_publish_block_data) & (COUNTER_OUT_EQ_1023))) ? s_reset : - - ((r_curr_state == s_reset) | - ((r_curr_state == s_idle) & ((i_USES_DAT == c_DAT_none) | ((i_USES_DAT != c_DAT_none) & (~i_CMD_TX_DONE))))) ? s_idle : - - ((r_curr_state == s_idle) & (i_USES_DAT == c_DAT_wide) & (i_CMD_TX_DONE)) ? s_reset_wide_data : - - ((r_curr_state == s_idle) & (i_USES_DAT == c_DAT_block) & (i_CMD_TX_DONE)) ? s_reset_block_data : - - ((r_curr_state == s_reset_wide_data) | - ((r_curr_state == s_idle) & (i_USES_DAT == c_DAT_busy) & (i_CMD_TX_DONE)) | - (r_curr_state == s_reset_block_data) | - ((r_curr_state == s_idle_for_start_bit) & (TIMER_OUT_GT_0) & (i_DAT0_Q != c_start_bit))) ? s_idle_for_start_bit : - - ((r_curr_state == s_idle_for_start_bit) & // Apparently R1b's busy signal is optional, - (TIMER_OUT_EQ_0) & // Even if it never shows up, - (i_USES_DAT == c_DAT_busy)) ? s_notify_r1b_completed : // pretend it did, & move on - - (((r_curr_state == s_idle_for_start_bit) & (TIMER_OUT_GT_0) & - (i_DAT0_Q == c_start_bit) & (i_USES_DAT == c_DAT_busy)) | - ((r_curr_state == s_read_r1b) & (TIMER_OUT_GT_0) & (i_DAT0_Q == c_busy_bit))) ? s_read_r1b : - - (((r_curr_state == s_read_r1b) & (TIMER_OUT_EQ_0)) | - ((r_curr_state == s_idle_for_start_bit) & (TIMER_OUT_EQ_0) & - (i_USES_DAT != c_DAT_busy))) ? s_error_time_out : - - ((r_curr_state == s_read_r1b) & (i_DAT0_Q != c_busy_bit)) ? s_notify_r1b_completed : - - (((r_curr_state == s_idle_for_start_bit) & (TIMER_OUT_GT_0) & (i_DAT0_Q == c_start_bit) & - (i_USES_DAT == c_DAT_wide)) | - ((r_curr_state == s_rx_wide_data) & (COUNTER_OUT_LT_128))) ? s_rx_wide_data : - - (((r_curr_state == s_idle_for_start_bit) & (TIMER_OUT_GT_0) & - (i_DAT0_Q == c_start_bit) & (i_USES_DAT == c_DAT_block)) | - ((r_curr_state == s_rx_block_data) & (COUNTER_OUT_LT_1023))) ? s_rx_block_data : - - (((r_curr_state == s_rx_wide_data) & (COUNTER_OUT_EQ_128)) | - ((r_curr_state == s_rx_block_data) & (COUNTER_OUT_EQ_1023)) | - ((r_curr_state == s_rx_crc16) & - (((i_USES_DAT == c_DAT_wide) & (COUNTER_OUT_LT_144)) | - ((i_USES_DAT == c_DAT_block) & (COUNTER_OUT_LT_1040))))) ? s_rx_crc16 : - - ((r_curr_state == s_rx_crc16) & - (((i_USES_DAT == c_DAT_wide) & (COUNTER_OUT_EQ_144)) | - ((i_USES_DAT == c_DAT_block) & (COUNTER_OUT_EQ_1040))) & - (~i_DATA_CRC16_GOOD)) ? s_error_crc16_fail : - - ((r_curr_state == s_rx_crc16) & (i_USES_DAT == c_DAT_wide) & (COUNTER_OUT_EQ_144) & - (i_DATA_CRC16_GOOD)) ? s_publish_wide_data : - - ((r_curr_state == s_rx_crc16) & - (i_USES_DAT == c_DAT_block) & (COUNTER_OUT_EQ_1040) & (i_DATA_CRC16_GOOD)) ? s_reset_nibble_counter : - - ((r_curr_state == s_reset_nibble_counter)) ? s_publish_block_data : - - s_reset; - - assign o_TIMER_IN = (r_curr_state == s_reset) & (i_SD_CLK_SELECTED == c_slow_clock) ? Identify_Timer_In : Data_TX_Timer_In; - - assign o_TIMER_LOAD = ((r_curr_state == s_reset) | - (r_curr_state == s_reset_block_data)); - - assign o_TIMER_EN = ((r_curr_state == s_idle_for_start_bit) | - (r_curr_state == s_read_r1b)); - - // Nibble Counter module - assign o_COUNTER_RST = (r_curr_state == s_reset) | (r_curr_state == s_reset_nibble_counter); - - assign o_COUNTER_EN = ((r_curr_state == s_rx_block_data) | - (r_curr_state == s_rx_wide_data) | - (r_curr_state == s_rx_crc16)) | (r_curr_state == s_publish_block_data); - - // CRC16 Generation module - assign o_CRC16_RST = (r_curr_state == s_reset); - - assign o_CRC16_EN = ((r_curr_state == s_rx_block_data) | - (r_curr_state == s_rx_wide_data) | - (r_curr_state == s_rx_crc16)); - - // Flip Flop Module (for R1b) - assign o_BUSY_RST = (r_curr_state == s_reset); - - //o_BUSY_EN = '1' when ((r_curr_state == s_idle_for_start_bit) | - // (r_curr_state == s_read_r1b)) else - // '0'; - assign o_BUSY_EN = 1'b1; // Always sample data - - // DAT Storage Modules - assign o_NIBO_EN = (r_curr_state == s_rx_block_data); - - // To sd_cmd_fsm - assign o_DAT_RX_DONE = ((r_curr_state == s_error_time_out) | - (r_curr_state == s_notify_r1b_completed) | - (r_curr_state == s_error_crc16_fail) | - (r_curr_state == s_publish_wide_data) | - (r_curr_state == s_publish_block_data)); - - assign o_ERROR_DAT_TIMES_OUT = (r_curr_state == s_error_time_out); - - - // o_RESEND_READ_WIDE (Error! This is not defined. Indicates switch command must be re-rent), - // should be a function of block busy logic - - // For Communication with core - assign o_DATA_VALID = (r_curr_state == s_publish_block_data); - - assign o_LAST_NIBBLE = ((r_curr_state == s_publish_block_data) - & (COUNTER_OUT_EQ_1023)) | (r_curr_state == s_error_time_out); // notify done if errors occur - - // o_ERROR_CRC16 (note: saved to flip flop because otherwise is only 1 clock cycle, not what I want) - assign o_DAT_ERROR_FD_RST = (r_curr_state == s_reset_block_data) | (r_curr_state == s_reset_wide_data); - assign o_DAT_ERROR_FD_EN = (r_curr_state == s_rx_crc16); - - - - - -endmodule diff --git a/pipelined/src/uncore/sdc/sd_top.sv b/pipelined/src/uncore/sdc/sd_top.sv deleted file mode 100644 index 3cac14ed9..000000000 --- a/pipelined/src/uncore/sdc/sd_top.sv +++ /dev/null @@ -1,652 +0,0 @@ -/////////////////////////////////////////// -// sd_top.sv -// -// Written: Richard Davis -// Modified: Ross Thompson September 19, 2021 -// -// Purpose: SD card controller -// -// A component of the CORE-V-WALLY configurable RISC-V project. -// -/// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - -`include "wally-config.vh" - -module sd_top #(parameter g_COUNT_WIDTH = 8) ( - input logic CLK, // 1.2 GHz (1.0 GHz typical) - input logic a_RST, // Reset signal (Must be held for minimum of 24 clock cycles) - // a_RST MUST COME OUT OF RESET SYNCHRONIZED TO THE 1.2 GHZ CLOCK! - // io_SD_CMD_z : inout std_logic; // SD CMD Bus - (* mark_debug = "true" *)input logic i_SD_CMD, // CMD Response from card - (* mark_debug = "true" *)output logic o_SD_CMD, // CMD Command from host - (* mark_debug = "true" *)output logic o_SD_CMD_OE, // Direction of SD_CMD - (* mark_debug = "true" *)input logic [3:0] i_SD_DAT, // SD DAT Bus - (* mark_debug = "true" *)output logic o_SD_CLK, // SD CLK Bus - // For communication with core cpu - input logic [32:9] i_BLOCK_ADDR, // see "Addressing" in parts.fods (only 8GB total capacity is used) - output logic o_READY_FOR_READ, // tells core that initialization sequence is completed and - // sd card is ready to read a 512 byte block to the core. - // Held high during idle until i_READ_REQUEST is received - output logic o_SD_RESTARTING, // inform core the need to restart - - input logic i_READ_REQUEST, // After Ready for read is sent to the core, the core will - // pulse this bit high to indicate it wants the block at this address - output logic [3:0] o_DATA_TO_CORE, // nibble being sent to core when DATA block is - output logic [4095:0] ReadData, // full 512 bytes to Bus - // being published - output logic o_DATA_VALID, // held high while data being read to core to indicate that it is valid - output logic o_LAST_NIBBLE, // pulse when last nibble is sent - output logic [2:0] o_ERROR_CODE_Q, // indicates which error occured - output logic o_FATAL_ERROR, // indicates that the FATAL ERROR register has updated - // For tuning - input logic [g_COUNT_WIDTH-1:0] i_COUNT_IN_MAX, - input logic LIMIT_SD_TIMERS -); - - localparam logic c_CMD = 1'b0; - localparam logic c_ACMD = 1'b1; - - // packet bit names - localparam logic c_start_bit = 1'b0; // bit 47 - localparam logic c_stop_bit = 1'b1; // bit 0, AKA "end bit" - // transmitter bit, bit 46 - localparam logic c_tx_host_command = 1'b1; - localparam logic c_tx_card_response = 1'b0; - - // response types - localparam logic [2:0] c_response_type_R0_NONE = 3'd0; - localparam logic [2:0] c_response_type_R1_NORMAL = 3'd1; - localparam logic [2:0] c_response_type_R2_CID_CSD = 3'd2; - localparam logic [2:0] c_response_type_R3_OCR = 3'd3; - localparam logic [2:0] c_response_type_R6_RCA = 3'd6; - localparam logic [2:0] c_response_type_R7_CIC = 3'd7; - - // uses dat - localparam logic [1:0] c_DAT_none = 2'b00; - localparam logic [1:0] c_DAT_busy = 2'b01; - localparam logic [1:0] c_DAT_wide = 2'b10; - localparam logic [1:0] c_DAT_block = 2'b11; - - // tx source selection - localparam logic [1:0] c_tx_low = 2'b00; - localparam logic [1:0] c_tx_high = 2'b01; - localparam logic [1:0] c_tx_head = 2'b10; - localparam logic [1:0] c_tx_tail = 2'b11; - - // command indexes - localparam logic [45:40] c_Go_Idle_State = 6'd00; // CMD0 - localparam logic [45:40] c_All_Send_CID = 6'd02; // CMD2 - localparam logic [45:40] c_SD_Send_RCA = 6'd03; // CMD3 - localparam logic [45:40] c_Switch_Function = 6'd06; // CMD6 - localparam logic [45:40] c_Set_Bus_Width = 6'd06; // ACMD6 - localparam logic [45:40] c_Select_Card = 6'd07; // CMD7 - localparam logic [45:40] c_Send_IF_State = 6'd08; // CMD8 - localparam logic [45:40] c_Read_Single_Block = 6'd17; // CMD17 - localparam logic [45:40] c_SD_Send_OCR = 6'd41; // ACMD41 - localparam logic [45:40] c_App_Command = 6'd55; // CMD55 - - // bitmasks - localparam logic [127:96] c_CMD0_mask_check_redo_bits = 32'h00000000; // Go_Idle_State - localparam logic [127:96] c_CMD0_ans_dont_redo = 32'h00000000; - localparam logic [127:96] c_CMD0_mask_check_error_bits = 32'h00000000; - localparam logic [127:96] c_CMD0_ans_error_free = 32'h00000000; - - localparam logic [127:96] c_CMD2_mask_check_redo_bits = 32'h00000000; // All_Send_CID - localparam logic [127:96] c_CMD2_ans_dont_redo = 32'h00000000; - localparam logic [127:96] c_CMD2_mask_check_error_bits = 32'h00000000; - localparam logic [127:96] c_CMD2_ans_error_free = 32'h00000000; - - localparam logic [127:96] c_CMD3_mask_check_redo_bits = 32'h00000000; // SD_Send_RCA - localparam logic [127:96] c_CMD3_ans_dont_redo = 32'h00000000; - localparam logic [127:96] c_CMD3_mask_check_error_bits = 32'h00002000; - localparam logic [127:96] c_CMD3_ans_error_free = 32'h00000000; - - localparam logic [127:96] c_CMD6_mask_check_redo_bits = 32'h00000000; // Switch_Function - localparam logic [127:96] c_CMD6_ans_dont_redo = 32'h00000000; - localparam logic [127:96] c_CMD6_mask_check_error_bits = 32'h82380000; - localparam logic [127:96] c_CMD6_ans_error_free = 32'h00000000; - - localparam logic [127:96] c_ACMD6_mask_check_redo_bits = 32'h00000000; // Set_Bus_Width - localparam logic [127:96] c_ACMD6_ans_dont_redo = 32'h00000000; - localparam logic [127:96] c_ACMD6_mask_check_error_bits = 32'h8F398020; - localparam logic [127:96] c_ACMD6_ans_error_free = 32'h00000020; - - localparam logic [127:96] c_CMD7_mask_check_redo_bits = 32'h00000000; // Select_Card - localparam logic [127:96] c_CMD7_ans_dont_redo = 32'h00000000; - localparam logic [127:96] c_CMD7_mask_check_error_bits = 32'h0F398000; - localparam logic [127:96] c_CMD7_ans_error_free = 32'h00000000; - - localparam logic [127:96] c_CMD8_mask_check_redo_bits = 32'h00000000; // Send_IF_State - localparam logic [127:96] c_CMD8_ans_dont_redo = 32'h00000000; - localparam logic [127:96] c_CMD8_mask_check_error_bits = 32'h00000FFF; - localparam logic [127:96] c_CMD8_ans_error_free = 32'h000001FF; - - localparam logic [127:96] c_CMD17_mask_check_redo_bits = 32'h00000000; // Read_Single_Block - localparam logic [127:96] c_CMD17_ans_dont_redo = 32'h00000000; - localparam logic [127:96] c_CMD17_mask_check_error_bits = 32'hCF398000; - localparam logic [127:96] c_CMD17_ans_error_free = 32'h00000000; - - localparam logic [127:96] c_ACMD41_mask_check_redo_bits = 32'h80000000; //32'h80000000; // SD_Send_OCR - localparam logic [127:96] c_ACMD41_ans_dont_redo = 32'h80000000; //32'h80000000; - localparam logic [127:96] c_ACMD41_mask_check_error_bits = 32'h41FF8000; // 32'h41FF8000; - localparam logic [127:96] c_ACMD41_ans_error_free = 32'h40FF8000; // 32'h40FF8000 - - localparam logic [127:96] c_CMD55_mask_check_redo_bits = 32'h00000000; // App_Command - localparam logic [127:96] c_CMD55_ans_dont_redo = 32'h00000000; - localparam logic [127:96] c_CMD55_mask_check_error_bits = 32'h0F398000; - localparam logic [127:96] c_CMD55_ans_error_free = 32'h00000000; - - localparam logic [127:96] c_ACMD55_mask_check_redo_bits = 32'h00000000; // App_Command - localparam logic [127:96] c_ACMD55_ans_dont_redo = 32'h00000000; - localparam logic [127:96] c_ACMD55_mask_check_error_bits = 32'h0F398000; - localparam logic [127:96] c_ACMD55_ans_error_free = 32'h00000000; - - // SD_CMD_FSM Connections - logic w_TIMER_LOAD, w_TIMER_EN; - logic [18:0] w_TIMER_IN; - logic [18:0] r_TIMER_OUT; - logic w_COUNTER_LOAD, w_COUNTER_EN; - logic [7:0] w_COUNTER_IN; - logic [7:0] r_COUNTER_OUT; - logic w_SD_CLK_EN; - logic w_CLOCK_CHANGE_DONE, w_START_CLOCK_CHANGE; // to clk fsm - logic w_HS_TO_INIT_CLK_DIVIDER_RST; - (* mark_debug = "true" *)logic w_IC_RST, w_IC_EN, w_IC_UP_DOWN; - (* mark_debug = "true" *)logic w_SD_CMD_OE; - logic w_TX_PISO40_LOAD, w_TX_PISO40_EN; - logic w_TX_PISO8_LOAD, w_TX_PISO8_EN; - logic w_TX_CRC7_PIPO_RST, w_TX_CRC7_PIPO_EN; - logic [1:0] w_TX_SOURCE_SELECT; - logic w_CMD_TX_IS_CMD55_RST; - logic w_CMD_TX_IS_CMD55_EN; - logic w_RX_SIPO48_RST, w_RX_SIPO48_EN; - (* mark_debug = "true" *)logic [39:8] r_RESPONSE_CONTENT; - (* mark_debug = "true" *)logic [45:40] r_RESPONSE_INDEX; - logic w_RX_CRC7_SIPO_RST, w_RX_CRC7_SIPO_EN; - logic [6:0] r_RX_CRC7_Q; - logic w_RCA_REGISTER_RST, w_RCA_REGISTER_EN; - logic w_CMD_TX_DONE; - logic w_DAT_RX_DONE; - logic w_DAT_ERROR_FD_RST_DAT, w_DAT_ERROR_FD_RST_CMD, w_DAT_ERROR_FD_RST, w_DAT_ERROR_FD_EN; - (* mark_debug = "true" *)logic r_DAT_ERROR_Q; // CRC16 error or time out - (* mark_debug = "true" *)logic w_NOT_DAT_ERROR_Q; // '0'=no error, '1'=tx error on DAT bus - (* mark_debug = "true" *)logic w_ERROR_DAT_TIMES_OUT; - (* mark_debug = "true" *)logic w_FATAL_ERROR; - (* mark_debug = "true" *)logic [2:0] r_ERROR_CODE_Q; // indicates which fatal error occured - - // Communication with core - (* mark_debug = "true" *)logic w_READY_FOR_READ; - (* mark_debug = "true" *)logic w_READ_REQUEST; - (* mark_debug = "true" *)logic [3:0] r_DATA_TO_CORE; - (* mark_debug = "true" *)logic w_DATA_VALID; - (* mark_debug = "true" *)logic w_LAST_NIBBLE; - - //SD_DAT_FSM Connections - logic w_DAT_TIMER_LOAD, w_DAT_TIMER_EN; - logic w_DAT_COUNTER_RST, w_DAT_COUNTER_EN; - logic w_CRC16_EN, w_CRC16_RST; - logic w_BUSY_RST, w_BUSY_EN; - logic w_NIBO_EN; - logic w_DATA_CRC16_GOOD; - logic [22:0] w_DAT_TIMER_IN; - logic [22:0] r_DAT_TIMER_OUT; - logic [10:0] r_DAT_COUNTER_OUT; - (* mark_debug = "true" *)logic [3:0] r_DAT_Q; - - // RCA Register - logic [15:0] w_RCA_D_Q; - logic [15:0] r_RCA_Q2; - - // Multiplexer Logics - logic [132:0] w_instruction_control_bits; - logic [132:130] w_R_TYPE ; - logic [129:128] w_USES_DAT ; - logic [127:96] w_NO_REDO_MASK ; - logic [95:64] w_NO_REDO_ANS ; - logic [63:32] w_NO_ERROR_MASK ; - logic [31:0] w_NO_ERROR_ANS ; - logic [45:40] w_command_index ; - logic [39:8] w_command_arguments ; - logic [47:8] w_command_head ; - (* mark_debug = "true" *)logic [6:0] w_OPCODE_Q ; - - // TOP_LEVEL Connections - logic [40:9] w_BLOCK_ADDR ; - (* mark_debug = "true" *)logic [3:0] r_IC_OUT ; - logic [2:0] r_command_index_is_55_history ; // [0] is live index, [1] is currently saved index, [2] is index of previous command - logic r_previous_command_index_was_55_q; // is index of previous command 55, wired to r_command_index_is_55_history[2] - logic r_ACMD_Q; // if the previous command sent to the SD card successfully had index 55, then the SD card thinks the current command is ACMD - - // TX - logic [45:8] w_command_content; // first 40 bits of command packet - logic w_tx_head_Q; // transmission of first part of command packet - logic w_tx_tail_Q; // transmission of last part of command packet - logic [7:0] r_command_tail; // last 8 bits of command packet - logic [6:0] r_TX_CRC7; - - // RX - logic [47:0] r_RX_RESPONSE; - - // Tri state IO Driver BC18MIMS - logic w_SD_CMD_TX_Q; // Write Data - logic w_SD_CMD_RX; // Read Data - - - // CLOCKS - //logic r_CLK_HS := '0'; // 50 MHz Divided Clock [static] - //logic r_SD_CLK_ungated := '0'; // Selected clock before it is clock gated - - //logic r_SD_CLK := '0'; // GATED CLOCKS - logic r_TO_SD_CLK; // What is actually sent to the SD card - - logic w_G_CLK_SD_EN; - logic r_CLK_SD, r_G_CLK_SD; // clocks - logic [15:0] r_CLK_FSM_RST ; // a_rst logic delayed by one 1.2 GHz period - logic w_SD_CLK_SELECTED; - - //DAT FSM Connections - logic [15:0] r_DAT3_CRC16, r_DAT2_CRC16, r_DAT1_CRC16; - logic [15:0] r_DAT0_CRC16; - - assign w_BLOCK_ADDR = {8'h00, i_BLOCK_ADDR}; // (40 downto 36 are zero since card is 64 GB) - // (35 downto 32 are zero since memeory is only 8GB total) - - assign o_READY_FOR_READ = w_READY_FOR_READ; - assign w_READ_REQUEST = i_READ_REQUEST; - assign o_DATA_TO_CORE = r_DATA_TO_CORE; - assign o_DATA_VALID = w_DATA_VALID; - assign o_LAST_NIBBLE = (w_LAST_NIBBLE | w_FATAL_ERROR); // indicate done if (last nibble OR Fatal Error go high) - assign o_FATAL_ERROR = w_FATAL_ERROR; - - sd_cmd_fsm my_sd_cmd_fsm - ( - .CLK(r_G_CLK_SD), - .i_RST(a_RST), - .o_TIMER_LOAD(w_TIMER_LOAD), - .o_TIMER_EN(w_TIMER_EN), - .o_TIMER_IN(w_TIMER_IN), - .i_TIMER_OUT(r_TIMER_OUT), - .o_COUNTER_LOAD(w_COUNTER_LOAD), - .o_COUNTER_EN(w_COUNTER_EN), - .o_COUNTER_IN(w_COUNTER_IN), - .i_COUNTER_OUT(r_COUNTER_OUT), - .o_SD_CLK_EN(w_SD_CLK_EN), - .i_CLOCK_CHANGE_DONE(w_CLOCK_CHANGE_DONE), - .o_START_CLOCK_CHANGE(w_START_CLOCK_CHANGE), - .o_IC_RST(w_IC_RST), - .o_IC_EN(w_IC_EN), - .o_IC_UP_DOWN(w_IC_UP_DOWN), - .i_IC_OUT(r_IC_OUT), - .i_USES_DAT(w_USES_DAT), - .i_OPCODE(w_OPCODE_Q), - .i_R_TYPE(w_R_TYPE), - .i_NO_REDO_MASK(w_NO_REDO_MASK), - .i_NO_REDO_ANS(w_NO_REDO_ANS), - .i_NO_ERROR_MASK(w_NO_ERROR_MASK), - .i_NO_ERROR_ANS(w_NO_ERROR_ANS), - .o_SD_CMD_OE(w_SD_CMD_OE), - .o_TX_PISO40_LOAD(w_TX_PISO40_LOAD), - .o_TX_PISO40_EN(w_TX_PISO40_EN), - .o_TX_PISO8_LOAD(w_TX_PISO8_LOAD), - .o_TX_PISO8_EN(w_TX_PISO8_EN), - .o_TX_CRC7_PIPO_RST(w_TX_CRC7_PIPO_RST), - .o_TX_CRC7_PIPO_EN(w_TX_CRC7_PIPO_EN), - .o_TX_SOURCE_SELECT(w_TX_SOURCE_SELECT), - .o_CMD_TX_IS_CMD55_RST(w_CMD_TX_IS_CMD55_RST), - .o_CMD_TX_IS_CMD55_EN(w_CMD_TX_IS_CMD55_EN), - .i_SD_CMD_RX(w_SD_CMD_RX), - .o_RX_SIPO48_RST(w_RX_SIPO48_RST), - .o_RX_SIPO48_EN(w_RX_SIPO48_EN), - .i_RESPONSE_CONTENT(r_RESPONSE_CONTENT), - .i_RESPONSE_INDEX(r_RESPONSE_INDEX), - .o_RX_CRC7_SIPO_RST(w_RX_CRC7_SIPO_RST), - .o_RX_CRC7_SIPO_EN(w_RX_CRC7_SIPO_EN), - .i_RX_CRC7(r_RX_CRC7_Q), - .o_RCA_REGISTER_RST(w_RCA_REGISTER_RST), - .o_RCA_REGISTER_EN(w_RCA_REGISTER_EN), - .o_CMD_TX_DONE(w_CMD_TX_DONE), - .i_DAT_RX_DONE(w_DAT_RX_DONE), - .i_ERROR_CRC16(w_NOT_DAT_ERROR_Q), - .i_ERROR_DAT_TIMES_OUT(w_ERROR_DAT_TIMES_OUT), - .i_READ_REQUEST(w_READ_REQUEST), - .o_READY_FOR_READ(w_READY_FOR_READ), - .o_SD_RESTARTING(o_SD_RESTARTING), - .o_DAT_ERROR_FD_RST(w_DAT_ERROR_FD_RST_CMD), - .o_ERROR_CODE_Q(r_ERROR_CODE_Q), - .o_FATAL_ERROR(w_FATAL_ERROR), - .LIMIT_SD_TIMERS(LIMIT_SD_TIMERS)); - - assign o_ERROR_CODE_Q = r_ERROR_CODE_Q; - - sd_dat_fsm my_sd_dat_fsm - (.CLK(r_G_CLK_SD), - .i_RST(a_RST), - .o_TIMER_LOAD(w_DAT_TIMER_LOAD), - .o_TIMER_EN(w_DAT_TIMER_EN), - .o_TIMER_IN(w_DAT_TIMER_IN), - .i_TIMER_OUT(r_DAT_TIMER_OUT), - .i_SD_CLK_SELECTED(w_SD_CLK_SELECTED), - .o_COUNTER_RST(w_DAT_COUNTER_RST), - .o_COUNTER_EN(w_DAT_COUNTER_EN), - .i_COUNTER_OUT(r_DAT_COUNTER_OUT), - .o_CRC16_EN(w_CRC16_EN), - .o_CRC16_RST(w_CRC16_RST), - .i_DATA_CRC16_GOOD(w_DATA_CRC16_GOOD), - .o_BUSY_RST(w_BUSY_RST), - .o_BUSY_EN(w_BUSY_EN), - .i_DAT0_Q(r_DAT_Q[0]), - .o_NIBO_EN(w_NIBO_EN), - .i_USES_DAT(w_USES_DAT), - .i_CMD_TX_DONE(w_CMD_TX_DONE), - .o_DAT_RX_DONE(w_DAT_RX_DONE), - .o_ERROR_DAT_TIMES_OUT(w_ERROR_DAT_TIMES_OUT), - .o_DATA_VALID(w_DATA_VALID), - .o_LAST_NIBBLE(w_LAST_NIBBLE), - .o_DAT_ERROR_FD_RST(w_DAT_ERROR_FD_RST_DAT), - .o_DAT_ERROR_FD_EN(w_DAT_ERROR_FD_EN), - .LIMIT_SD_TIMERS(LIMIT_SD_TIMERS)); - - assign w_DAT_ERROR_FD_RST = w_DAT_ERROR_FD_RST_CMD | w_DAT_ERROR_FD_RST_DAT; - - flopenr #(1) dat_error_fd - (.clk(r_G_CLK_SD), - .d(w_DATA_CRC16_GOOD), - .q(r_DAT_ERROR_Q), - .en(w_DAT_ERROR_FD_EN), - .reset((w_DAT_ERROR_FD_RST))); - - assign w_NOT_DAT_ERROR_Q = ~r_DAT_ERROR_Q; - - up_down_counter #(23) dat_fsm_timer - ( - .CountIn(w_DAT_TIMER_IN), - .CountOut(r_DAT_TIMER_OUT), - .Load(w_DAT_TIMER_LOAD), - .Enable(w_DAT_TIMER_EN), - .UpDown(1'b0), // Count DOWN only - .clk(r_G_CLK_SD), - .reset(1'b0)); // No Reset, Just Load - - SDCcounter #(11) dat_nibble_counter - ( - .CountIn('0), - .CountOut(r_DAT_COUNTER_OUT), - .Load(1'b0), - .Enable(w_DAT_COUNTER_EN), - .clk(r_G_CLK_SD), - .reset(w_DAT_COUNTER_RST)); - - regfile_p2r1w1_nibo #(.DEPTH(10), .WIDTH(4) ) regfile_cmd17_data_block // Nibble In - Nibble Out (NINO) - (.clk(r_G_CLK_SD), - .we1(w_NIBO_EN), - .ra1(r_DAT_COUNTER_OUT[9:0]), // Nibble Read (to core) Address - .rd1(r_DATA_TO_CORE), // output nibble to core - .Rd1All(ReadData), - .wa1(r_DAT_COUNTER_OUT[9:0]), // Nibble Write (to host) Address - .wd1(r_DAT_Q)); // input nibble from card - - crc16_sipo_np_ce crc16_sipo_np_ce_DAT3 - (.CLK(r_G_CLK_SD), - .RST(w_CRC16_RST), - .i_enable(w_CRC16_EN), - .i_message_bit(r_DAT_Q[3]), - .o_crc16(r_DAT3_CRC16)); - - crc16_sipo_np_ce crc16_sipo_np_ce_DAT2 - (.CLK(r_G_CLK_SD), - .RST(w_CRC16_RST), - .i_enable(w_CRC16_EN), - .i_message_bit(r_DAT_Q[2]), - .o_crc16(r_DAT2_CRC16)); - - crc16_sipo_np_ce crc16_sipo_np_ce_DAT1 - (.CLK(r_G_CLK_SD), - .RST(w_CRC16_RST), - .i_enable(w_CRC16_EN), - .i_message_bit(r_DAT_Q[1]), - .o_crc16(r_DAT1_CRC16)); - - crc16_sipo_np_ce crc16_sipo_np_ce_DAT0 - (.CLK(r_G_CLK_SD), - .RST(w_CRC16_RST), - .i_enable(w_CRC16_EN), - .i_message_bit(r_DAT_Q[0]), - .o_crc16(r_DAT0_CRC16)); - - - assign w_DATA_CRC16_GOOD = ({r_DAT3_CRC16, r_DAT2_CRC16, r_DAT1_CRC16, r_DAT0_CRC16}) == 64'h0000000000000000; - - flopenr #(4) busy_bit_fd - (.en(w_BUSY_EN), - .clk(r_G_CLK_SD), - .d(i_SD_DAT), - .q(r_DAT_Q), - .reset(w_BUSY_RST)); - - sd_clk_fsm my_clk_fsm - (.CLK(CLK), - .i_RST(a_RST), - .o_DONE(w_CLOCK_CHANGE_DONE), - .i_START(w_START_CLOCK_CHANGE), - .o_HS_TO_INIT_CLK_DIVIDER_RST(w_HS_TO_INIT_CLK_DIVIDER_RST), - .o_SD_CLK_SELECTED(w_SD_CLK_SELECTED), - .i_FATAL_ERROR(w_FATAL_ERROR), - .o_G_CLK_SD_EN(w_G_CLK_SD_EN)); - - up_down_counter #(19) cmd_fsm_timer - (.CountIn(w_TIMER_IN), - .CountOut(r_TIMER_OUT), - .Load(w_TIMER_LOAD), - .Enable(w_TIMER_EN), - .UpDown(1'b0), // Count DOWN only - .clk(r_G_CLK_SD), - .reset(1'b0)); // No Reset, Just Load - - up_down_counter #(8) cmd_fsm_counter - (.CountIn(w_COUNTER_IN), - .CountOut(r_COUNTER_OUT), - .Load(w_COUNTER_LOAD), - .Enable(w_COUNTER_EN), - .UpDown(1'b0), // Count DOWN only - .clk(r_G_CLK_SD), - .reset(1'b0)); // No RESET, only LOAD - - up_down_counter #(4) instruction_counter - (.CountIn('0), // No CountIn, only RESET - .CountOut(r_IC_OUT), - .Load(1'b0), // No LOAD, only RESET - .Enable(w_IC_EN), - .UpDown(w_IC_UP_DOWN), - .clk(r_G_CLK_SD), - .reset(w_IC_RST | a_RST)); - - // Clock selection - clkdivider #(g_COUNT_WIDTH) slow_clk_divider // Divide 50 MHz to <400 KHz (Initial clock) - (.i_COUNT_IN_MAX(i_COUNT_IN_MAX), - .i_EN(w_SD_CLK_SELECTED), - //.i_EN(1'b1), - //.i_RST(w_HS_TO_INIT_CLK_DIVIDER_RST), - .i_RST(a_RST), - .i_CLK(CLK), - .o_CLK(r_CLK_SD)); - - clockgater sd_clk_gater // Select which clock goes to components - (.CLK(r_CLK_SD), - .E(w_G_CLK_SD_EN | a_RST), - .SE(1'b0), - .ECLK(r_G_CLK_SD)); - - clockgater to_sd_clk_gater // Enable activity on the SD_CLK line - (.CLK(r_G_CLK_SD), - .E(w_SD_CLK_EN), - .SE(1'b0), - .ECLK(r_TO_SD_CLK)); - - flopenr #(16) RCA_register_CE - (.clk(r_G_CLK_SD), - .en(w_RCA_REGISTER_EN), - .d(w_RCA_D_Q), - .q(r_RCA_Q2), - .reset(w_RCA_REGISTER_RST)); - - // ACMD_Detector - flopenr #(1) index_history_fd_2to1 - (.clk(r_G_CLK_SD), - .reset(w_CMD_TX_IS_CMD55_RST), - .en(w_CMD_TX_IS_CMD55_EN), - .d(r_command_index_is_55_history[2]), - .q(r_command_index_is_55_history[1])); - - flopenr #(1) index_history_fd_1to0 - (.clk(r_G_CLK_SD), - .reset(w_CMD_TX_IS_CMD55_RST), - .en(w_CMD_TX_IS_CMD55_EN), - .d(r_command_index_is_55_history[1]), - .q(r_command_index_is_55_history[0])); - - - - assign r_command_index_is_55_history[2] = (w_command_index == 55); - - - assign r_previous_command_index_was_55_q = r_command_index_is_55_history[0]; - assign r_ACMD_Q = r_previous_command_index_was_55_q; // if the previous command WAS 55, the current command is ACMD - - assign o_SD_CLK = r_TO_SD_CLK; - - - - // Multiplexers - //Fetch index and argument of command - assign w_command_content = (r_IC_OUT == 0) ? ({c_Go_Idle_State, 32'h00000000}) : // CMD0 - (r_IC_OUT == 1) ? ({c_Send_IF_State, 32'h000001FF}) : // CMD8 - (r_IC_OUT == 2) ? ({c_App_Command, 32'h00000000}) : // CMD55 - (r_IC_OUT == 3) ? ({c_SD_Send_OCR, 32'h40FF8000}) : // ACMD41 - (r_IC_OUT == 4) ? ({c_All_Send_CID, 32'h00000000}) : // CMD2 - (r_IC_OUT == 5) ? ({c_SD_Send_RCA, 32'h00000000}) : // CMD3 - (r_IC_OUT == 6) ? ({c_Select_Card, r_RCA_Q2[15:0], 16'h0000}) : // CMD7 - (r_IC_OUT == 7) ? ({c_App_Command, r_RCA_Q2[15:0], 16'h0000}) : // CMD55 - (r_IC_OUT == 8) ? ({c_Set_Bus_Width, 32'h00000002}) : // ACMD6 - (r_IC_OUT == 9) ? ({c_Switch_Function, 32'h80FFFFF1}) : // CMD6 - (r_IC_OUT == 10) ? ({c_Read_Single_Block, w_BLOCK_ADDR}) : // CMD17 - ({c_Read_Single_Block, w_BLOCK_ADDR}); // when in doubt just send CMD17 - - assign w_command_index = w_command_content[45:40]; - assign w_command_arguments = w_command_content[39:8]; - assign w_command_head = {c_start_bit, c_tx_host_command, w_command_content}; - - assign w_OPCODE_Q = {r_ACMD_Q, w_command_index}; - - // TX - - crc7_pipo tx_crc7_pipo - (.CLK(r_G_CLK_SD), - .i_DATA(w_command_head), - .i_CRC_ENABLE(w_TX_CRC7_PIPO_EN), - .RST(w_TX_CRC7_PIPO_RST), - .o_CRC(r_TX_CRC7)); - - assign r_command_tail = {r_TX_CRC7, c_stop_bit}; - - piso_generic_ce #(40) tx_piso40_command_head - (.clk(r_G_CLK_SD), - .i_load(w_TX_PISO40_LOAD), - .i_data(w_command_head), - .i_en(w_TX_PISO40_EN), - .o_data(w_tx_head_Q)); - - piso_generic_ce #(8) tx_piso8_command_tail - (.clk(r_G_CLK_SD), - .i_load(w_TX_PISO8_LOAD), - .i_data(r_command_tail), - .i_en(w_TX_PISO8_EN), - .o_data(w_tx_tail_Q)); - - assign w_SD_CMD_TX_Q = (w_TX_SOURCE_SELECT == c_tx_low) ? 1'b0 : - (w_TX_SOURCE_SELECT == c_tx_high) ? 1'b1 : - (w_TX_SOURCE_SELECT == c_tx_head) ? w_tx_head_Q : - (w_TX_SOURCE_SELECT == c_tx_tail) ? w_tx_tail_Q : - 1'b0; - - assign w_SD_CMD_RX = i_SD_CMD; - - flopenr #(1) sd_cmd_out_reg - (.d(w_SD_CMD_TX_Q), - .q(o_SD_CMD), - .en(1'b1), - .clk(~r_G_CLK_SD), - .reset(a_RST)); - - flopenr #(1) sd_cmd_out_oe_reg - (.d(w_SD_CMD_OE), - .q(o_SD_CMD_OE), - .en(1'b1), - .clk(~r_G_CLK_SD), - .reset(a_RST)); - - // RX - sipo_generic_ce #(48) rx_sipo48_response_content - (.clk(r_G_CLK_SD), - .rst(w_RX_SIPO48_RST), - .i_enable(w_RX_SIPO48_EN), - .i_message_bit(w_SD_CMD_RX), - .o_data(r_RX_RESPONSE)); - - assign r_RESPONSE_CONTENT = r_RX_RESPONSE[39:8]; - assign r_RESPONSE_INDEX = r_RX_RESPONSE[45:40]; - assign w_RCA_D_Q = r_RESPONSE_CONTENT[39:24]; - - crc7_sipo_np_ce rx_crc7_sipo - (.clk(r_G_CLK_SD), - .rst(w_RX_CRC7_SIPO_RST), - .i_enable(w_RX_CRC7_SIPO_EN), - .i_message_bit(w_SD_CMD_RX), - .o_crc7(r_RX_CRC7_Q)); - - // Fetch control bits using r_opcode - assign w_instruction_control_bits = (w_OPCODE_Q == ({c_CMD, c_Go_Idle_State})) ? ({c_response_type_R0_NONE, c_DAT_none, c_CMD0_mask_check_redo_bits, c_CMD0_ans_dont_redo, c_CMD0_mask_check_error_bits, c_CMD0_ans_error_free}) : // CMD0 - - (w_OPCODE_Q == ({c_CMD, c_All_Send_CID})) ? ({c_response_type_R2_CID_CSD, c_DAT_none, c_CMD2_mask_check_redo_bits, c_CMD2_ans_dont_redo, c_CMD2_mask_check_error_bits, c_CMD2_ans_error_free}): // CMD2 - - (w_OPCODE_Q == ({c_CMD, c_SD_Send_RCA})) ? ({c_response_type_R6_RCA, c_DAT_none, c_CMD3_mask_check_redo_bits, c_CMD3_ans_dont_redo, c_CMD3_mask_check_error_bits, c_CMD3_ans_error_free}) : // CMD3 - - (w_OPCODE_Q == ({c_CMD, c_Switch_Function})) ? ({c_response_type_R1_NORMAL, c_DAT_wide, c_CMD6_mask_check_redo_bits, c_CMD6_ans_dont_redo, c_CMD6_mask_check_error_bits, c_CMD6_ans_error_free}): // CMD6 - - (w_OPCODE_Q == ({c_ACMD, c_Set_Bus_Width})) ? ({c_response_type_R1_NORMAL, c_DAT_none, c_ACMD6_mask_check_redo_bits, c_ACMD6_ans_dont_redo, c_ACMD6_mask_check_error_bits, c_ACMD6_ans_error_free}): //ACMD6 - - (w_OPCODE_Q == ({c_CMD, c_Select_Card})) ? ({c_response_type_R1_NORMAL, c_DAT_busy, c_CMD7_mask_check_redo_bits, c_CMD7_ans_dont_redo, c_CMD7_mask_check_error_bits, c_CMD7_ans_error_free}): // CMD7 - - (w_OPCODE_Q == ({c_CMD, c_Send_IF_State})) ? ({c_response_type_R7_CIC, c_DAT_none, c_CMD8_mask_check_redo_bits, c_CMD8_ans_dont_redo, c_CMD8_mask_check_error_bits, c_CMD8_ans_error_free}): // CMD8 - - (w_OPCODE_Q == ({c_CMD, c_Read_Single_Block})) ? ({c_response_type_R1_NORMAL, c_DAT_block, c_CMD17_mask_check_redo_bits, c_CMD17_ans_dont_redo, c_CMD17_mask_check_error_bits, c_CMD17_ans_error_free}): // CMD17 - - (w_OPCODE_Q == ({c_ACMD, c_SD_Send_OCR})) ? ({c_response_type_R3_OCR, c_DAT_none, c_ACMD41_mask_check_redo_bits, c_ACMD41_ans_dont_redo, c_ACMD41_mask_check_error_bits, c_ACMD41_ans_error_free}) : //ACMD41 - - (w_OPCODE_Q == ({c_CMD, c_App_Command})) ? ({c_response_type_R1_NORMAL, c_DAT_none, c_CMD55_mask_check_redo_bits, c_CMD55_ans_dont_redo, c_CMD55_mask_check_error_bits, c_CMD55_ans_error_free}) : // CMD55 - - (w_OPCODE_Q == ({c_ACMD, c_App_Command})) ? ({c_response_type_R1_NORMAL, c_DAT_none, c_ACMD55_mask_check_redo_bits, c_ACMD55_ans_dont_redo, c_ACMD55_mask_check_error_bits, c_ACMD55_ans_error_free}) : //ACMD55 - - ({c_response_type_R1_NORMAL, c_DAT_none, c_ACMD55_mask_check_redo_bits, c_ACMD55_ans_dont_redo, c_ACMD55_mask_check_error_bits, c_ACMD55_ans_error_free}); // when in doubt just send ACMD55 - - assign w_R_TYPE = w_instruction_control_bits[132:130]; - assign w_USES_DAT = w_instruction_control_bits[129:128]; - assign w_NO_REDO_MASK = w_instruction_control_bits[127:96]; - assign w_NO_REDO_ANS = w_instruction_control_bits[95:64]; - assign w_NO_ERROR_MASK = w_instruction_control_bits[63:32]; - assign w_NO_ERROR_ANS = w_instruction_control_bits[31:0]; - - -endmodule - diff --git a/pipelined/src/uncore/sdc/sd_top_wrapper.v b/pipelined/src/uncore/sdc/sd_top_wrapper.v deleted file mode 100644 index 96d1bbc46..000000000 --- a/pipelined/src/uncore/sdc/sd_top_wrapper.v +++ /dev/null @@ -1,98 +0,0 @@ - -/////////////////////////////////////////// -// sd_top_wrapper.sv -// -// Written: Richard Davis -// Modified: Ross Thompson September 19, 2021 -// -// Purpose: SD card controller wrapper -// -// A component of the CORE-V-WALLY configurable RISC-V project. -// -/// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - - -module sd_top_wrapper #(parameter g_COUNT_WIDTH = 8) ( - input logic clk_in1_p, - input logic clk_in1_n, - input logic a_RST, // Reset signal (Must be held for minimum of 24 clock cycles) - // a_RST MUST COME OUT OF RESET SYNCHRONIZED TO THE 1.2 GHZ CLOCK! - // io_SD_CMD_z : inout std_logic; // SD CMD Bus - inout SD_CMD, // CMD Response from card - input logic [3:0] i_SD_DAT, // SD DAT Bus - output logic o_SD_CLK, // SD CLK Bus - // For communication with core cpu - output logic o_READY_FOR_READ, // tells core that initialization sequence is completed and - // sd card is ready to read a 512 byte block to the core. - // Held high during idle until i_READ_REQUEST is received - output logic o_SD_RESTARTING, // inform core the need to restart - - input logic i_READ_REQUEST, // After Ready for read is sent to the core, the core will - // pulse this bit high to indicate it wants the block at this address - output logic [3:0] o_DATA_TO_CORE, // nibble being sent to core when DATA block is being published - output logic o_DATA_VALID // held high while data being read to core to indicate that it is valid -); - - wire CLK; - wire LIMIT_SD_TIMERS; - wire [g_COUNT_WIDTH-1:0] i_COUNT_IN_MAX; - wire [4095:0] ReadData; // full 512 bytes to Bus - wire [32:9] i_BLOCK_ADDR; // see "Addressing" in parts.fods (only 8GB total capacity is used) - wire o_SD_CMD; // CMD Command from host - wire i_SD_CMD; // CMD Command from host - wire o_SD_CMD_OE; // Direction of SD_CMD - wire [2:0] o_ERROR_CODE_Q; // indicates which error occured - wire o_FATAL_ERROR; // indicates that the FATAL ERROR register has updated - wire o_LAST_NIBBLE; // pulse when last nibble is sent - - assign LIMIT_SD_TIMERS = 1'b0; - assign i_COUNT_IN_MAX = -8'd62; - assign i_BLOCK_ADDR = 23'h0; - - clk_wiz_0 clk_wiz_0(.clk_in1_p(clk_in1_p), - .clk_in1_n(clk_in1_n), - .reset(1'b0), - .clk_out1(CLK), - .locked(locked)); - - IOBUF SDCMDIODriver(.T(~o_SD_CMD_OE), - .I(o_SD_CMD), - .O(i_SD_CMD), - .IO(SD_CMD)); - - - sd_top #(g_COUNT_WIDTH) - sd_top(.CLK(CLK), - .a_RST(a_RST), - .i_SD_CMD(i_SD_CMD), // CMD Response from card - .o_SD_CMD(o_SD_CMD), // CMD Command from host - .o_SD_CMD_OE(o_SD_CMD_OE), // Direction of SD_CMD - .i_SD_DAT(i_SD_DAT), // SD DAT Bus - .o_SD_CLK(o_SD_CLK), // SD CLK Bus - .i_BLOCK_ADDR(i_BLOCK_ADDR), // see "Addressing" in parts.fods (only 8GB total capacity is used) - .o_READY_FOR_READ(o_READY_FOR_READ), // tells core that initialization sequence is completed and - .o_SD_RESTARTING(o_SD_RESTARTING), // inform core the need to restart - .i_READ_REQUEST(i_READ_REQUEST), // After Ready for read is sent to the core, the core will - .o_DATA_TO_CORE(o_DATA_TO_CORE), // nibble being sent to core when DATA block is - .ReadData(ReadData), // full 512 bytes to Bus - .o_DATA_VALID(o_DATA_VALID), // held high while data being read to core to indicate that it is valid - .o_LAST_NIBBLE(o_LAST_NIBBLE), // pulse when last nibble is sent - .o_ERROR_CODE_Q(o_ERROR_CODE_Q), // indicates which error occured - .o_FATAL_ERROR(o_FATAL_ERROR), // indicates that the FATAL ERROR register has updated - .i_COUNT_IN_MAX(i_COUNT_IN_MAX), - .LIMIT_SD_TIMERS(LIMIT_SD_TIMERS) - ); - -endmodule diff --git a/pipelined/src/uncore/sdc/simple_timer.sv b/pipelined/src/uncore/sdc/simple_timer.sv deleted file mode 100644 index 09dbf048c..000000000 --- a/pipelined/src/uncore/sdc/simple_timer.sv +++ /dev/null @@ -1,54 +0,0 @@ -/////////////////////////////////////////// -// simple_timer.sv -// -// Written: Ross Thompson September 20, 2021 -// Modified: -// -// Purpose: SD card controller -// -// A component of the CORE-V-WALLY configurable RISC-V project. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - -`include "wally-config.vh" - -module simple_timer #(parameter BUS_WIDTH = 4) ( - input logic [BUS_WIDTH-1:0] VALUE, - input logic START, - output logic FLAG, - input logic RST, - input logic CLK -); - - - logic [BUS_WIDTH-1:0] count; - logic timer_en; - - assign timer_en = count != 0; - - always_ff @(posedge CLK, posedge RST) begin - if (RST) begin - count <= '0; - end else if (START) begin - count <= VALUE - 1'b1; - end else if(timer_en) begin - count <= count - 1'b1; - end - end - - assign FLAG = count != 0; - -endmodule - diff --git a/pipelined/src/uncore/sdc/sipo_generic_ce.sv b/pipelined/src/uncore/sdc/sipo_generic_ce.sv deleted file mode 100644 index 7b749b654..000000000 --- a/pipelined/src/uncore/sdc/sipo_generic_ce.sv +++ /dev/null @@ -1,51 +0,0 @@ -/////////////////////////////////////////// -// sipo_generic_ce -// -// Written: Richard Davis -// Modified: Ross Thompson September 20, 2021 -// -// Purpose: serial to n-bit parallel shift register using register_ce. -// When given a n-bit word as input transmit the message serially MSB (leftmost) -// bit first. -// -// A component of the CORE-V-WALLY configurable RISC-V project. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - -`include "wally-config.vh" - -module sipo_generic_ce #(g_BUS_WIDTH) ( - input logic clk, - input logic rst, - input logic i_enable, // data valid, write to register - input logic i_message_bit, // serial data - output logic [g_BUS_WIDTH-1:0] o_data // message received, parallel data -); - - logic [g_BUS_WIDTH-1:0] w_reg_d; - logic [g_BUS_WIDTH-1:0] r_reg_q; - - flopenr #(g_BUS_WIDTH) shiftReg - (.d(w_reg_d), - .q(r_reg_q), - .en(i_enable), - .reset(rst), - .clk(clk)); - - assign w_reg_d = {r_reg_q[g_BUS_WIDTH-2:0], i_message_bit}; - - assign o_data = r_reg_q; - -endmodule diff --git a/pipelined/src/uncore/sdc/up_down_counter.sv b/pipelined/src/uncore/sdc/up_down_counter.sv deleted file mode 100644 index 4424386ac..000000000 --- a/pipelined/src/uncore/sdc/up_down_counter.sv +++ /dev/null @@ -1,45 +0,0 @@ -/////////////////////////////////////////// -// counter.sv -// -// Written: Ross Thompson -// Modified: -// -// Purpose: basic up counter -// -// A component of the CORE-V-WALLY configurable RISC-V project. -// -// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1 -// -// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file -// except in compliance with the License, or, at your option, the Apache License version 2.0. You -// may obtain a copy of the License at -// -// https://solderpad.org/licenses/SHL-2.1/ -// -// Unless required by applicable law or agreed to in writing, any work distributed under the -// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, -// either express or implied. See the License for the specific language governing permissions -// and limitations under the License. -//////////////////////////////////////////////////////////////////////////////////////////////// - -`include "wally-config.vh" - -module up_down_counter #(parameter integer WIDTH=32) ( - input logic [WIDTH-1:0] CountIn, - output logic [WIDTH-1:0] CountOut, - input logic Load, - input logic Enable, - input logic UpDown, - input logic clk, - input logic reset -); - - logic [WIDTH-1:0] NextCount; - logic [WIDTH-1:0] CountP1; - - assign CountP1 = UpDown ? CountOut + 1'b1 : CountOut - 1'b1; - assign NextCount = Load ? CountIn : CountP1; - flopenr #(WIDTH) reg1(clk, reset, Enable | Load, NextCount, CountOut); -endmodule - -