From 33f8a649562f120870000bcc96aece02b96c1ed7 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sat, 21 Jul 2018 11:52:58 +0100 Subject: [PATCH] add verilog sd-wishbone --- src/bsv/bsv_lib/sd/sd.tgz | Bin 0 -> 10155 bytes src/bsv/bsv_lib/sd/sd_bus.sv | 201 +++++++++++++ src/bsv/bsv_lib/sd/sd_clock_divider.v | 81 ++++++ src/bsv/bsv_lib/sd/sd_cmd_serial_host.v | 329 +++++++++++++++++++++ src/bsv/bsv_lib/sd/sd_crc_16.v | 43 +++ src/bsv/bsv_lib/sd/sd_crc_7.v | 34 +++ src/bsv/bsv_lib/sd/sd_data_serial_host.sv | 334 ++++++++++++++++++++++ src/bsv/bsv_lib/sd/sd_defines.h | 105 +++++++ src/bsv/bsv_lib/sd/sd_top.sv | 174 +++++++++++ 9 files changed, 1301 insertions(+) create mode 100644 src/bsv/bsv_lib/sd/sd.tgz create mode 100644 src/bsv/bsv_lib/sd/sd_bus.sv create mode 100644 src/bsv/bsv_lib/sd/sd_clock_divider.v create mode 100644 src/bsv/bsv_lib/sd/sd_cmd_serial_host.v create mode 100644 src/bsv/bsv_lib/sd/sd_crc_16.v create mode 100644 src/bsv/bsv_lib/sd/sd_crc_7.v create mode 100644 src/bsv/bsv_lib/sd/sd_data_serial_host.sv create mode 100644 src/bsv/bsv_lib/sd/sd_defines.h create mode 100644 src/bsv/bsv_lib/sd/sd_top.sv diff --git a/src/bsv/bsv_lib/sd/sd.tgz b/src/bsv/bsv_lib/sd/sd.tgz new file mode 100644 index 0000000000000000000000000000000000000000..120aa40279e6d2ada2299041cb732fae4425c830 GIT binary patch literal 10155 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 INIT_DELAY) begin + next_state = IDLE; + end + else begin + next_state = INIT; + end + end + IDLE: begin + if (start_i) begin + next_state = SETUP_CRC; + end + else begin + next_state = IDLE; + end + end + SETUP_CRC: + next_state = WRITE; + WRITE: + if (counter >= BITS_TO_SEND && with_response) begin + next_state = READ_WAIT; + end + else if (counter >= BITS_TO_SEND) begin + next_state = FINISH_RD_WR; + end + else begin + next_state = WRITE; + end + READ_WAIT: + if ((wait_reg_o >= 3) && !cmd_dat_reg) begin // allow time for bus to change direction + next_state = READ; + end + else if (wait_reg_o >= timeout_i) begin // prevent hang if card did not respond + next_state = FINISH_RD_WR; + end + else begin + next_state = READ_WAIT; + end + READ: + if (counter >= resp_len+8) begin + next_state = FINISH_RD_WR; + end + else begin + next_state = READ; + end + FINISH_RD_WR: + if (start_i) + next_state = FINISH_RD_WR; + else + next_state = IDLE; + default: + next_state = INIT; + endcase +end + +always @(posedge sd_clk or posedge rst) +begin: COMMAND_DECODER + if (rst) begin + resp_len <= 0; + with_response <= 0; + with_data <= 0; + cmd_buff <= 0; + end + else begin + if (start_i == 1) begin + resp_len <= setting_i[1] ? RESP_SIZE_LONG : RESP_SIZE_SHORT; + with_response <= setting_i[0]; + with_data <= setting_i[2]; + cmd_buff <= {2'b01,cmd_i}; + end + end +end + +//----------------Seq logic------------ +always @(posedge sd_clk or posedge rst) +begin: FSM_SEQ + if (rst) begin + state <= INIT; + end + else begin + state <= next_state; + end +end + +//-------------OUTPUT_LOGIC------- +always @(posedge sd_clk or posedge rst) +begin: FSM_OUT + if (rst) begin + crc_enable <= 0; + cmd_oe_o = 1; + cmd_out_o = 1; + response_o <= 0; + finish_o <= 0; + crc_rst <= 1; + crc_bit <= 0; + index_ok_o <= 0; + crc_ok_o <= 0; + counter <= 0; + cmd_dat_reg <= 0; + packet_o <= 0; + start_data_o <= 0; + wait_reg_o <= 0; + end + else begin + case(state) + INIT: begin + counter <= counter+1; + cmd_oe_o = 1; + cmd_out_o = 1; + end + IDLE: begin + cmd_oe_o = 0; //Put CMD to Z + counter <= 0; + crc_rst <= 1; + crc_enable <= 0; + index_ok_o <= 0; + finish_o <= 0; + start_data_o <= 0; + end + SETUP_CRC: begin + crc_rst <= 0; + crc_enable <= 1; + response_o <= 0; + packet_o <= 0; + crc_bit <= cmd_buff[CMD_SIZE-1]; + end + WRITE: begin + cmd_dat_reg <= 1'b1; + if (counter < BITS_TO_SEND-8) begin // 1->40 CMD, (41 >= CNT && CNT <=47) CRC, 48 stop_bit + cmd_oe_o = 1; + cmd_out_o = cmd_buff[CMD_SIZE-1-counter]; + if (counter < BITS_TO_SEND-9) begin //1 step ahead + crc_bit <= cmd_buff[CMD_SIZE-2-counter]; + end else begin + crc_enable <= 0; + end + end + else if (counter < BITS_TO_SEND-1) begin + cmd_oe_o = 1; + crc_enable <= 0; + cmd_out_o = crc_val_o[BITS_TO_SEND-counter-2]; + end + else if (counter == BITS_TO_SEND-1) begin + cmd_oe_o = 1; + cmd_out_o = 1'b1; + end + else begin + cmd_oe_o = 0; + cmd_out_o = 1'b1; + end + counter <= counter+1; + wait_reg_o <= 0; + if (cmd_oe_o) packet_o <= {packet_o[BITS_TO_SEND-2:0],cmd_out_o}; + end + READ_WAIT: begin + cmd_dat_reg <= cmd_dat_i; + crc_enable <= 0; + crc_rst <= 1; + counter <= 1; + cmd_oe_o = 0; + wait_reg_o <= wait_reg_o + 1; + end + READ: begin + cmd_dat_reg <= cmd_dat_i; + crc_rst <= 0; + crc_enable <= (resp_len != RESP_SIZE_LONG || counter > 7); + cmd_oe_o = 0; + if (counter <= resp_len) + crc_bit <= cmd_dat_reg; + else + begin + crc_enable <= 0; + end + if (counter <= resp_len+7) begin + response_o <= {response_o[RESP_SIZE_LONG+5:0],cmd_dat_reg}; + end + else begin + crc_enable <= 0; + crc_ok_o <= (response_o[6:0] == crc_val_o); + start_data_o <= with_data; + end + counter <= counter + 1; + end + FINISH_RD_WR: begin + index_ok_o <= (cmd_buff[37:32] == response_o[125:120]); + finish_o <= 1; + crc_enable <= 0; + counter <= 0; + cmd_oe_o = 0; + end // case: FINISH_RD_WR + default:; + endcase + end +end + +endmodule + + diff --git a/src/bsv/bsv_lib/sd/sd_crc_16.v b/src/bsv/bsv_lib/sd/sd_crc_16.v new file mode 100644 index 0000000..5dbd439 --- /dev/null +++ b/src/bsv/bsv_lib/sd/sd_crc_16.v @@ -0,0 +1,43 @@ +// ========================================================================== +// CRC Generation Unit - Linear Feedback Shift Register implementation +// (c) Kay Gorontzi, GHSi.de, distributed under the terms of LGPL +// ========================================================================== +module sd_crc_16(BITVAL, ENABLE, BITSTRB, CLEAR, CRC); + input BITVAL; // Next input bit + input ENABLE; // Enable calculation + input BITSTRB; // Current bit valid (Clock) + input CLEAR; // Init CRC value + output [15:0] CRC; // Current output CRC value + + reg [15:0] CRC; // We need output registers + wire inv; + + assign inv = BITVAL ^ CRC[15]; // XOR required? + + always @(posedge BITSTRB or posedge CLEAR) begin + if (CLEAR) begin + CRC <= 0; // Init before calculation + end + else begin + if (ENABLE == 1) begin + CRC[15] <= CRC[14]; + CRC[14] <= CRC[13]; + CRC[13] <= CRC[12]; + CRC[12] <= CRC[11] ^ inv; + CRC[11] <= CRC[10]; + CRC[10] <= CRC[9]; + CRC[9] <= CRC[8]; + CRC[8] <= CRC[7]; + CRC[7] <= CRC[6]; + CRC[6] <= CRC[5]; + CRC[5] <= CRC[4] ^ inv; + CRC[4] <= CRC[3]; + CRC[3] <= CRC[2]; + CRC[2] <= CRC[1]; + CRC[1] <= CRC[0]; + CRC[0] <= inv; + end + end + end + +endmodule diff --git a/src/bsv/bsv_lib/sd/sd_crc_7.v b/src/bsv/bsv_lib/sd/sd_crc_7.v new file mode 100644 index 0000000..7cb5bae --- /dev/null +++ b/src/bsv/bsv_lib/sd/sd_crc_7.v @@ -0,0 +1,34 @@ +// ========================================================================== +// CRC Generation Unit - Linear Feedback Shift Register implementation +// (c) Kay Gorontzi, GHSi.de, distributed under the terms of LGPL +// ========================================================================== +module sd_crc_7(BITVAL, ENABLE, BITSTRB, CLEAR, CRC); + input BITVAL; // Next input bit + input ENABLE; // Enable calculation + input BITSTRB; // Current bit valid (Clock) + input CLEAR; // Init CRC value + output [6:0] CRC; // Current output CRC value + + reg [6:0] CRC; // We need output registers + wire inv; + + assign inv = BITVAL ^ CRC[6]; // XOR required? + + always @(posedge BITSTRB or posedge CLEAR) begin + if (CLEAR) begin + CRC <= 0; // Init before calculation + end + else begin + if (ENABLE == 1) begin + CRC[6] <= CRC[5]; + CRC[5] <= CRC[4]; + CRC[4] <= CRC[3]; + CRC[3] <= CRC[2] ^ inv; + CRC[2] <= CRC[1]; + CRC[1] <= CRC[0]; + CRC[0] <= inv; + end + end + end + +endmodule diff --git a/src/bsv/bsv_lib/sd/sd_data_serial_host.sv b/src/bsv/bsv_lib/sd/sd_data_serial_host.sv new file mode 100644 index 0000000..971dc38 --- /dev/null +++ b/src/bsv/bsv_lib/sd/sd_data_serial_host.sv @@ -0,0 +1,334 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// WISHBONE SD Card Controller IP Core //// +//// //// +//// sd_data_serial_host.v //// +//// //// +//// This file is part of the WISHBONE SD Card //// +//// Controller IP Core project //// +//// http://opencores.org/project,sd_card_controller //// +//// //// +//// Description //// +//// Module resposible for sending and receiving data through //// +//// 4-bit sd card data interface //// +//// //// +//// Author(s): //// +//// - Marek Czerski, ma.czerski@gmail.com //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2013 Authors //// +//// //// +//// Based on original work by //// +//// Adam Edvardsson (adam.edvardsson@orsoc.se) //// +//// //// +//// Copyright (C) 2009 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +`include "sd_defines.h" + +module sd_data_serial_host( + input sd_clk, + input rst, + //Tx Fifo + input [31:0] data_in, + output reg rd, + //Rx Fifo + output reg [31:0] data_out, + output reg we, + //tristate data + output reg DAT_oe_o, + output reg [3:0] DAT_dat_o, + input [3:0] DAT_dat_i, + //Control signals + input [`BLKSIZE_W-1:0] blksize, + input bus_4bit, + input [`BLKCNT_W-1:0] blkcnt, + input [1:0] start, + input [1:0] byte_alignment, + input [31:0] timeout_i, + output sd_data_busy, + output busy, + output crc_ok, + output reg finish_o, + output reg [31:0] wait_reg_o, + output reg [`BLKSIZE_W-1+4:0] transf_cnt_o + ); + +reg [4:0] crc_s; +reg [3:0] crc_lane_ok; +reg [15:0] crc_din[3:0]; +wire [15:0] crc_calc[3:0]; +reg [31:0] data_out0; +reg we0; +reg [3:0] DAT_dat_reg; +reg [`BLKSIZE_W-1+4:0] data_cycles; +reg bus_4bit_reg; +//CRC16 + reg [4:0] crc_in; +reg crc_rst; +parameter SIZE = 7; +reg [SIZE-1:0] state; +reg [SIZE-1:0] next_state; +parameter IDLE = 7'b0000001; +parameter WRITE_DAT = 7'b0000010; +parameter WRITE_CRC = 7'b0000100; +parameter WRITE_BUSY = 7'b0001000; +parameter READ_WAIT = 7'b0010000; +parameter READ_DAT = 7'b0100000; +parameter FINISH = 7'b1000000; +reg [2:0] crc_status; +reg busy_int; +reg [`BLKSIZE_W-1:0] blksize_reg; +reg [4:0] crc_c; + reg [3:0] crnt_din; +reg [4:0] data_index; + + integer k; +genvar i; +generate + for(i=0; i<4; i=i+1) begin: CRC_16_gen + sd_crc_16 CRC_16_i (crc_in[i], crc_in[4], ~sd_clk, crc_rst, crc_calc[i]); + end +endgenerate + +assign busy = (state != IDLE) && (state != FINISH); +assign sd_data_busy = !DAT_dat_reg[0]; +assign crc_ok = &crc_lane_ok; + +always @(posedge sd_clk or posedge rst) +begin: FSM_OUT + if (rst) begin + state <= IDLE; + DAT_oe_o <= 0; + crc_in <= 0; + crc_rst <= 1; + transf_cnt_o <= 0; + crc_c <= 15; + rd <= 0; + crc_c <= 0; + DAT_dat_o <= 0; + crc_status <= 0; + crc_lane_ok <= 0; + crc_s <= 0; + we0 <= 0; + we <= 0; + data_out0 <= 0; + busy_int <= 0; + data_index <= 0; + data_cycles <= 0; + bus_4bit_reg <= 0; + wait_reg_o <= 0; + finish_o <= 0; + DAT_dat_reg <= 0; + data_out <= 0; + transf_cnt_o <= 0; + end + else begin + // sd data input pad register + DAT_dat_reg <= DAT_dat_i; + crnt_din = 4'hf; + if (we0) data_out <= data_out0; + we <= we0; + case(state) + IDLE: begin + for (k = 0; k < 4; k=k+1) + crc_din[k] <= 0; + DAT_oe_o <= 0; + DAT_dat_o <= 4'b1111; + crc_in <= 0; + crc_rst <= 1; + transf_cnt_o <= 0; + crc_c <= 16; + crc_status <= 0; + crc_lane_ok <= 0; + crc_s <= 0; + we0 <= 0; + rd <= 0; + data_index <= 0; + blksize_reg <= blksize; + data_cycles <= (bus_4bit ? {2'b0,blksize,1'b0} + 'd2 : {blksize,3'b0} + 'd8); + bus_4bit_reg <= bus_4bit; + wait_reg_o <= 0; + finish_o <= 0; + data_out <= 0; + if (start == 2'b01) + state <= WRITE_DAT; + else if (start == 2'b10) + state <= READ_WAIT; + end + WRITE_DAT: begin + transf_cnt_o <= transf_cnt_o + 16'h1; + rd <= 0; + //special case + if (transf_cnt_o == 0) begin + crc_rst <= 0; + data_index <= 0; + crnt_din = bus_4bit_reg ? 4'h0 : 4'he; + rd <= 1; + DAT_oe_o <= 1; + DAT_dat_o <= crnt_din; + end + else if (transf_cnt_o < data_cycles+16) begin /* send the write data */ + if (bus_4bit_reg) begin + crnt_din = { + data_in[31-({data_index[2:0],2'b00})], + data_in[30-({data_index[2:0],2'b00})], + data_in[29-({data_index[2:0],2'b00})], + data_in[28-({data_index[2:0],2'b00})] + }; + if (data_index[2:0] == 3'h7 && transf_cnt_o < data_cycles-2) begin + begin + rd <= 1; + end + end + end + else begin + crnt_din = {3'h7, data_in[31-data_index]}; + if (data_index == 29/*not 31 - read delay !!!*/) begin + begin + rd <= 1; + end + end + end + data_index <= data_index + 5'h1; + if (transf_cnt_o < data_cycles-1) + begin + crc_in <= {1'b1,crnt_din}; + DAT_dat_o <= crnt_din; + end + else if (crc_c!=0) begin /* send the CRC */ + crc_in <= 0; + crc_c <= crc_c - 5'h1; + DAT_oe_o <= 1; + DAT_dat_o[0] <= crc_calc[0][crc_c-1]; + if (bus_4bit_reg) + DAT_dat_o[3:1] <= {crc_calc[3][crc_c-1], crc_calc[2][crc_c-1], crc_calc[1][crc_c-1]}; + else + DAT_dat_o[3:1] <= {3'h7}; + end + else /* send the stop bit */ + begin + crc_in <= 0; + DAT_oe_o <= 1; + DAT_dat_o <= 4'hf; + end + end + else begin /* wait for write ack */ + DAT_oe_o <= 0; + crc_s[4] <= DAT_dat_reg[0]; + if (!DAT_dat_reg[0]) + state <= WRITE_CRC; + end + end + WRITE_CRC: begin /* get write ack */ + DAT_oe_o <= 0; + crc_status <= crc_status + 3'h1; + crc_s[3-crc_status[1:0]] <= DAT_dat_reg[0]; + busy_int <= 1; + if (crc_status == 3) + state <= WRITE_BUSY; + end + WRITE_BUSY: begin /* wait for write completion */ + busy_int <= !DAT_dat_reg[0]; + if (!busy_int) + state <= FINISH; + end + READ_WAIT: begin /* wait for a start bit in read mode */ + DAT_oe_o <= 0; + crc_rst <= 0; + crc_in <= 0; + crc_c <= 15;// end + transf_cnt_o <= 0; + data_index <= 0; + wait_reg_o <= wait_reg_o + 1; + if ((wait_reg_o >= 3) && !DAT_dat_reg[0]) begin // allow time for bus to change direction + state <= READ_DAT; + end + else if (wait_reg_o >= timeout_i) begin // prevent hang if card did not respond + state <= FINISH; + end + end + READ_DAT: begin /* read the data and calculate CRC */ + we0 <= 0; + if (transf_cnt_o < data_cycles-2) begin + if (bus_4bit_reg) begin + if (&data_index[2:0]) + begin + we0 <= 1; + end; + data_out0[31-({data_index[2:0],2'b00})] <= DAT_dat_reg[3]; + data_out0[30-({data_index[2:0],2'b00})] <= DAT_dat_reg[2]; + data_out0[29-({data_index[2:0],2'b00})] <= DAT_dat_reg[1]; + data_out0[28-({data_index[2:0],2'b00})] <= DAT_dat_reg[0]; + end + else begin + if (&data_index) + begin + we0 <= 1; + end; + data_out0[31-data_index] <= DAT_dat_reg[0]; + end + data_index <= data_index + 5'h1; + crc_in <= {1'b1,DAT_dat_reg}; + transf_cnt_o <= transf_cnt_o + 16'h1; + end + else if (crc_c != 5'h1f) begin + for (k = 0; k < 4; k=k+1) + begin + crc_din[k][crc_c[3:0]] <= DAT_dat_reg[k]; + end + transf_cnt_o <= transf_cnt_o + 16'h1; + crc_in <= 0; + we0 <=0; + crc_c <= crc_c - 5'h1; + end + else + begin + for (k = 0; k < 4; k=k+1) + crc_lane_ok[k] <= crc_calc[k] == crc_din[k]; + state <= FINISH; + end + end // case: READ_DAT + FINISH: + begin + finish_o <= 1; + if (start == 2'b00) + state <= IDLE; + end + default: + state <= IDLE; + endcase; // case (state) + //abort + if (start == 2'b11) + state <= IDLE; + end +end + +endmodule + + + + + diff --git a/src/bsv/bsv_lib/sd/sd_defines.h b/src/bsv/bsv_lib/sd/sd_defines.h new file mode 100644 index 0000000..87d8133 --- /dev/null +++ b/src/bsv/bsv_lib/sd/sd_defines.h @@ -0,0 +1,105 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// WISHBONE SD Card Controller IP Core //// +//// //// +//// sd_defines.h //// +//// //// +//// This file is part of the WISHBONE SD Card //// +//// Controller IP Core project //// +//// http://opencores.org/project,sd_card_controller //// +//// //// +//// Description //// +//// Header file with common definitions //// +//// //// +//// Author(s): //// +//// - Marek Czerski, ma.czerski@gmail.com //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2013 Authors //// +//// //// +//// Based on original work by //// +//// Adam Edvardsson (adam.edvardsson@orsoc.se) //// +//// //// +//// Copyright (C) 2009 Authors //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// + +//global defines +`define BLKSIZE_W 12 +`define BLKCNT_W 16 +`define CMD_TIMEOUT_W 24 +`define DATA_TIMEOUT_W 24 + +//cmd module interrupts +`define INT_CMD_SIZE 5 +`define INT_CMD_CC 0 +`define INT_CMD_EI 1 +`define INT_CMD_CTE 2 +`define INT_CMD_CCRCE 3 +`define INT_CMD_CIE 4 + +//data module interrupts +`define INT_DATA_SIZE 5 +`define INT_DATA_CC 0 +`define INT_DATA_EI 1 +`define INT_DATA_CTE 2 +`define INT_DATA_CCRCE 3 +`define INT_DATA_CFE 4 + +//command register defines +`define CMD_REG_SIZE 14 +`define CMD_RESPONSE_CHECK 1:0 +`define CMD_BUSY_CHECK 2 +`define CMD_CRC_CHECK 3 +`define CMD_IDX_CHECK 4 +`define CMD_WITH_DATA 6:5 +`define CMD_INDEX 13:8 + +//register addreses +`define argument 8'h00 +`define command 8'h04 +`define resp0 8'h08 +`define resp1 8'h0c +`define resp2 8'h10 +`define resp3 8'h14 +`define data_timeout 8'h18 +`define controller 8'h1c +`define cmd_timeout 8'h20 +`define clock_d 8'h24 +`define reset 8'h28 +`define voltage 8'h2c +`define capa 8'h30 +`define cmd_isr 8'h34 +`define cmd_iser 8'h38 +`define data_isr 8'h3c +`define data_iser 8'h40 +`define blksize 8'h44 +`define blkcnt 8'h48 +`define dst_src_addr 8'h60 + +//wb module defines +`define RESET_BLOCK_SIZE 12'd511 +`define RESET_CLK_DIV 0 +`define SUPPLY_VOLTAGE_mV 3300 diff --git a/src/bsv/bsv_lib/sd/sd_top.sv b/src/bsv/bsv_lib/sd/sd_top.sv new file mode 100644 index 0000000..fad49e3 --- /dev/null +++ b/src/bsv/bsv_lib/sd/sd_top.sv @@ -0,0 +1,174 @@ +// +// (c) Copyright 2008 - 2013 Xilinx, Inc. All rights reserved. +// +// This file contains confidential and proprietary information +// of Xilinx, Inc. and is protected under U.S. and +// international copyright and other intellectual property +// laws. +// +// DISCLAIMER +// This disclaimer is not a license and does not grant any +// rights to the materials distributed herewith. Except as +// otherwise provided in a valid license issued to you by +// Xilinx, and to the maximum extent permitted by applicable +// law: (1) THESE MATERIALS ARE MADE AVAILABLE "AS IS" AND +// WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES +// AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING +// BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON- +// INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and +// (2) Xilinx shall not be liable (whether in contract or tort, +// including negligence, or under any other theory of +// liability) for any loss or damage of any kind or nature +// related to, arising under or in connection with these +// materials, including for any direct, or any indirect, +// special, incidental, or consequential loss or damage +// (including loss of data, profits, goodwill, or any type of +// loss or damage suffered as a result of any action brought +// by a third party) even if such damage or loss was +// reasonably foreseeable or Xilinx had been advised of the +// possibility of the same. +// +// CRITICAL APPLICATIONS +// Xilinx products are not designed or intended to be fail- +// safe, or for use in any application requiring fail-safe +// performance, such as life-support or safety devices or +// systems, Class III medical devices, nuclear facilities, +// applications related to the deployment of airbags, or any +// other applications that could lead to death, personal +// injury, or severe property or environmental damage +// (individually and collectively, "Critical +// Applications"). Customer assumes the sole risk and +// liability of any use of Xilinx products in Critical +// Applications, subject only to applicable laws and +// regulations governing limitations on product liability. +// +// THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS +// PART OF THIS FILE AT ALL TIMES. +// + +// Copyright 2015 ETH Zurich and University of Bologna. +// Copyright and related rights are licensed under the Solderpad Hardware +// License, Version 0.51 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law +// or agreed to in writing, software, hardware and materials distributed under +// this 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. +// See LICENSE for license details. + +`default_nettype none + +module sd_top( + input wire sd_clk, + input wire cmd_rst, + input wire data_rst, + input wire [2:0] setting_i, + input wire start_i, + input wire [31:0] arg_i, + input wire [5:0] cmd_i, + input wire [31:0] timeout_i, + input wire [2:0] sd_data_start_i, + input wire [1:0] sd_align_i, + input wire [15:0] sd_blkcnt_i, + input wire [11:0] sd_blksize_i, + input wire [31:0] sd_data_i, + input wire [3:0] sd_dat_to_host, + input wire sd_cmd_to_host, +//---------------Output ports--------------- + output wire [31:0] response0_o, + output wire [63:32] response1_o, + output wire [95:64] response2_o, + output wire [126:96] response3_o, + output wire [31:0] wait_o, + output wire [31:0] wait_data_o, + output wire [31:4] status_o, + output wire [31:0] packet0_o, + output wire [15:0] packet1_o, + output wire [6:0] crc_val_o, + output wire [6:0] crc_actual_o, + output wire finish_cmd_o, + output wire finish_data_o, + output wire crc_ok_o, + output wire index_ok_o, + output wire sd_rd_o, + output wire sd_we_o, + output wire [31:0] sd_data_o, + output wire [15:0] transf_cnt_o, + output wire [3:0] sd_dat_to_mem, + output wire sd_cmd_to_mem, + output wire sd_cmd_oe, + output wire sd_dat_oe, + output reg [8:0] sd_xfr_addr); + + reg sd_cmd_to_host_dly; + reg [3:0] sd_dat_to_host_dly; + + wire start_data; + wire data_crc_ok; + wire sd_busy, sd_data_busy; + + assign status_o = {1'b0,crc_val_o[6:0], + 1'b0,crc_actual_o[6:0], + 5'b0,finish_data_o,sd_data_busy,finish_cmd_o, + index_ok_o,crc_ok_o,data_crc_ok,sd_busy}; + +always @(negedge sd_clk) + begin + if (data_rst) + sd_xfr_addr <= 0; + else + begin + if (sd_rd_o|sd_we_o) + sd_xfr_addr <= sd_xfr_addr + 1; + end + sd_cmd_to_host_dly <= sd_cmd_to_host; + sd_dat_to_host_dly <= sd_dat_to_host; + end + +sd_cmd_serial_host cmd_serial_host0( + .sd_clk (sd_clk), + .rst (cmd_rst), + .setting_i (setting_i), + .cmd_i ({cmd_i,arg_i}), + .start_i (start_i), + .timeout_i (timeout_i), + .finish_o (finish_cmd_o), + .response_o ({response3_o,response2_o,response1_o,response0_o,crc_actual_o}), + .crc_ok_o (crc_ok_o), + .crc_val_o (crc_val_o), + .packet_o ({packet1_o,packet0_o}), + .index_ok_o (index_ok_o), + .wait_reg_o (wait_o), + .start_data_o(start_data), + .cmd_dat_i (sd_cmd_to_host_dly), + .cmd_out_o (sd_cmd_to_mem), + .cmd_oe_o (sd_cmd_oe) + ); + +sd_data_serial_host data_serial_host0( + .sd_clk (sd_clk), + .rst (data_rst), + .data_in (sd_data_i), + .rd (sd_rd_o), + .data_out (sd_data_o), + .we (sd_we_o), + .finish_o (finish_data_o), + .DAT_oe_o (sd_dat_oe), + .DAT_dat_o (sd_dat_to_mem), + .DAT_dat_i (sd_dat_to_host_dly), + .blksize (sd_blksize_i), + .bus_4bit (sd_data_start_i[2]), + .blkcnt (sd_blkcnt_i), + .start (start_data ? sd_data_start_i[1:0] : 2'b00), + .byte_alignment (sd_align_i), + .timeout_i (timeout_i), + .sd_data_busy (sd_data_busy), + .busy (sd_busy), + .wait_reg_o (wait_data_o), + .crc_ok (data_crc_ok), + .transf_cnt_o (transf_cnt_o) + ); + +endmodule // chip_top +`default_nettype wire -- 2.30.2