Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- `timescale 1ns / 1ps
- //////////////////////////////////////////////////////////////////////////////////
- // Company: Dept. of Computer Science, National Chiao Tung University
- // Engineer: Chun-Jen Tsai
- //
- // Create Date: 2017/05/08 15:29:41
- // Design Name:
- // Module Name: lab6
- // Project Name:
- // Target Devices:
- // Tool Versions:
- // Description: The sample top module of lab 6: sd card reader. The behavior of
- // this module is as follows
- // 1. When the SD card is initialized, display a message on the LCD.
- // If the initialization fails, an error message will be shown.
- // 2. The user can then press usr_btn[2] to trigger the sd card
- // controller to read the super block of the sd card (located at
- // block # 8192) into the SRAM memory.
- // 3. During SD card reading time, the four LED lights will be turned on.
- // They will be turned off when the reading is done.
- // 4. The LCD will then displayer the sector just been read, and the
- // first byte of the sector.
- // 5. Everytime you press usr_btn[2], the next byte will be displayed.
- //
- // Dependencies: clk_divider, LCD_module, debounce, sd_card
- //
- // Revision:
- // Revision 0.01 - File Created
- // Additional Comments:
- //
- //////////////////////////////////////////////////////////////////////////////////
- module lab7(
- // General system I/O ports
- input clk,
- input reset_n,
- input [3:0] usr_btn,
- output [3:0] usr_led,
- // SD card specific I/O ports
- output spi_ss,
- output spi_sck,
- output spi_mosi,
- input spi_miso,
- // 1602 LCD Module Interface
- output LCD_RS,
- output LCD_RW,
- output LCD_E,
- output [3:0] LCD_D
- );
- localparam [3:0] S_MAIN_INIT = 4'b0000, S_MAIN_IDLE = 4'b0001,
- S_MAIN_WAIT = 4'b0010, S_MAIN_READ = 4'b0011,
- S_MAIN_DONE = 4'b0100, S_MAIN_FIND = 4'b0101,
- S_MAIN_CAL = 4'b0110, S_MAIN_SHOW = 4'b0111;
- // Declare system variables
- wire btn_level, btn_pressed;
- reg prev_btn_level;
- reg [5:0] send_counter;
- reg [2:0] P, P_next;
- reg [9:0] sd_counter;
- reg [9:0] counter=0;
- reg [9:0] start_counter;
- reg [7:0] data_byte;
- reg [31:0] blk_addr;
- reg [31:0] start_blk_addr;
- reg [3:0] dlab_tag_match=0;
- reg start_flag=0;
- reg not_this_block;
- reg [127:0] row_A = "SD card cannot ";
- reg [127:0] row_B = "be initialized! ";
- reg [0:63] dlab_tag = "MATX_TAG";
- reg [0:56] print_out = " ";
- reg done_flag; // Signals the completion of reading one SD sector.
- reg [0:7] word="@", word_1="@", word_2='h1 ,word_3 = "!",word_4='h2, word_5, word_6, word_7;
- reg [0:31] p_addr, p_addr_1;
- reg flag=0;
- // Declare SD card interface signals
- wire clk_sel;
- wire clk_500k;
- reg rd_req;
- reg [31:0] rd_addr;
- wire init_finished;
- wire [7:0] sd_dout;
- wire sd_valid;
- reg read_fin=0, cal_fin=0;
- // Declare the control/data signals of an SRAM memory block
- wire [7:0] data_in;
- wire [7:0] data_out;
- wire [8:0] sram_addr;
- wire sram_we, sram_en;
- assign clk_sel = (init_finished)? clk : clk_500k; // clock for the SD controller
- assign usr_led = P;
- // for matrix
- reg [0:255] A_mat, B_mat;
- reg [7:0] A_save_count, B_save_count;
- clk_divider#(200) clk_divider0(
- .clk(clk),
- .reset(~reset_n),
- .clk_out(clk_500k)
- );
- debounce btn_db0(
- .clk(clk),
- .btn_input(usr_btn[2]),
- .btn_output(btn_level)
- );
- LCD_module lcd0(
- .clk(clk),
- .reset(~reset_n),
- .row_A(row_A),
- .row_B(row_B),
- .LCD_E(LCD_E),
- .LCD_RS(LCD_RS),
- .LCD_RW(LCD_RW),
- .LCD_D(LCD_D)
- );
- sd_card sd_card0(
- .cs(spi_ss),
- .sclk(spi_sck),
- .mosi(spi_mosi),
- .miso(spi_miso),
- .clk(clk_sel),
- .rst(~reset_n),
- .rd_req(rd_req),
- .block_addr(rd_addr),
- .init_finished(init_finished),
- .dout(sd_dout),
- .sd_valid(sd_valid)
- );
- sram ram0(
- .clk(clk),
- .we(sram_we),
- .en(sram_en),
- .addr(sram_addr),
- .data_i(data_in),
- .data_o(data_out)
- );
- //
- // Enable one cycle of btn_pressed per each button hit
- //
- always @(posedge clk) begin
- if (~reset_n)
- prev_btn_level <= 0;
- else
- prev_btn_level <= btn_level;
- end
- assign btn_pressed = (btn_level == 1 && prev_btn_level == 0)? 1 : 0;
- // ------------------------------------------------------------------------
- // The following code sets the control signals of an SRAM memory block
- // that is connected to the data output port of the SD controller.
- // Once the read request is made to the SD controller, 512 bytes of data
- // will be sequentially read into the SRAM memory block, one byte per
- // clock cycle (as long as the sd_valid signal is high).
- assign sram_we = sd_valid; // Write data into SRAM when sd_valid is high.
- assign sram_en = 1; // Always enable the SRAM block.
- assign data_in = sd_dout; // Input data always comes from the SD controller.
- assign sram_addr = sd_counter[8:0]; // Set the driver of the SRAM address signal.
- // End of the SRAM memory block
- // ------------------------------------------------------------------------
- // ------------------------------------------------------------------------
- // FSM of the SD card reader that reads the super block (512 bytes)
- always @(posedge clk) begin
- if (~reset_n) begin
- P <= S_MAIN_INIT;
- done_flag <= 0;
- end
- else begin
- P <= P_next;
- if (P == S_MAIN_DONE)
- done_flag <= 1;
- else if (P == S_MAIN_SHOW && P_next == S_MAIN_IDLE)
- done_flag <= 0;
- else
- done_flag <= done_flag;
- end
- end
- always @(*) begin // FSM next-state logic
- case (P)
- S_MAIN_INIT: // wait for SD card initialization
- if (init_finished == 1) P_next = S_MAIN_IDLE;
- else P_next = S_MAIN_INIT;
- S_MAIN_IDLE: // wait for button click
- if (btn_pressed == 1) P_next = S_MAIN_WAIT;
- else P_next = S_MAIN_IDLE;
- S_MAIN_WAIT: // issue a rd_req to the SD controller until it's ready
- P_next = S_MAIN_READ;
- S_MAIN_READ: // wait for the input data to enter the SRAM buffer
- if (sd_counter == 512) P_next = S_MAIN_DONE;
- else P_next = S_MAIN_READ;
- S_MAIN_DONE: // read byte 0 of the superblock from sram[]
- P_next = S_MAIN_FIND;
- S_MAIN_FIND:
- if (read_fin == 1) P_next = S_MAIN_CAL;
- else if (sd_counter =='d512) P_next = S_MAIN_WAIT;
- else P_next = S_MAIN_FIND;
- S_MAIN_CAL:
- if (cal_fin == 1) P_next = S_MAIN_SHOW;
- else P_next = S_MAIN_CAL;
- S_MAIN_SHOW:
- if (~reset_n) P_next = S_MAIN_INIT;
- else P_next = S_MAIN_SHOW;
- default:
- P_next = S_MAIN_IDLE;
- endcase
- end
- // FSM output logic: controls the 'rd_req' and 'rd_addr' signals.
- always @(*) begin
- rd_req = (P == S_MAIN_WAIT);
- rd_addr = blk_addr;
- end
- always @(posedge clk) begin
- if (~reset_n) begin
- counter <= 0;
- blk_addr <= 32'h2000;
- dlab_tag_match <=0;
- start_flag <= 0;
- flag <= 0;
- A_save_count <= 0;
- B_save_count <= 0;
- read_fin <= 0;
- end
- if (P==S_MAIN_WAIT) begin
- not_this_block <= 0;
- end
- if (P==S_MAIN_FIND) begin
- if(data_byte==dlab_tag[counter+:8]) begin
- dlab_tag_match = dlab_tag_match + 1;
- counter <= counter + 8;
- not_this_block <= 0;
- // if (dlab_tag_match == 'd1) word <= data_byte;
- // if (dlab_tag_match == 'd2) word_1 <= data_byte;
- // if (dlab_tag_match == 'd3) word_2 <= data_byte;
- // if (dlab_tag_match == 'd4) word_3 <= data_byte;
- // if (dlab_tag_match == 'd5) word_4 <= data_byte;
- // if (dlab_tag_match == 'd6) word_5 <= data_byte;
- // if (dlab_tag_match == 'd7) word_6 <= data_byte;
- if (dlab_tag_match == 'd8) begin
- start_flag <= 1;
- dlab_tag_match = dlab_tag_match+1;
- //word_7 <= data_byte;
- p_addr_1[0+:8]<=blk_addr[15:12];
- p_addr_1[8+:8]<=blk_addr[11:8];
- p_addr_1[16+:8]<=blk_addr[7:4];
- p_addr_1[24+:8]<=blk_addr[3:0];
- end
- end
- else begin
- dlab_tag_match <= 0;
- counter <= 0;
- end
- if (start_flag == 1) begin
- if ((A_save_count < 'd255) && (((data_byte >= "0") && (data_byte <= "9")) || ((data_byte >= "A") && (data_byte <= "E")))) begin
- A_mat[A_save_count+:8] <= data_byte;
- if (A_save_count==0) word <= "*";
- if (A_save_count==8) word_1 <= "!";
- if (A_save_count==16) word_2 <= "@";
- if (A_save_count==24) word_3 <= "&";
- A_save_count <= A_save_count + 'd8;
- end
- else if (B_save_count < 'd255 && ((data_byte >= "0" && data_byte <= "9") || (data_byte >= "A" && data_byte <= "E"))) begin
- B_mat[B_save_count+:8] <= data_byte;
- if (B_save_count==0) word_4 <= "o";
- if (B_save_count==8) word_5 <= "y";
- if (B_save_count==16) word_6 <= "t";
- if (B_save_count==24) word_7 <= "r";
- B_save_count <= B_save_count + 'd8;
- end
- if(B_save_count >='d255) read_fin <= 1;
- end
- end
- if (P == S_MAIN_FIND && sd_counter == 'd512) blk_addr <= blk_addr+1;
- end
- always @(posedge clk) begin
- if (~reset_n || (P == S_MAIN_READ && P_next == S_MAIN_DONE) || ((P == S_MAIN_DONE) && (P_next == S_MAIN_WAIT)) || ((P == S_MAIN_FIND) && (P_next == S_MAIN_WAIT)) || ((P == S_MAIN_DONE) && (P_next == S_MAIN_FIND)))
- sd_counter <= 0;
- else if ((P == S_MAIN_READ && sd_valid) ||(P == S_MAIN_DONE && P_next==S_MAIN_FIND) || (P==S_MAIN_DONE && sd_counter<512) || (P==S_MAIN_FIND && sd_counter<512) ||((P == S_MAIN_CAL) && (P_next==S_MAIN_SHOW)))
- sd_counter <= sd_counter + 1;
- end
- // FSM ouput logic: Retrieves the content of sram[] for display
- always @(posedge clk) begin
- if (~reset_n) data_byte <= 8'b0;
- else if (sram_en && (P == S_MAIN_DONE || P == S_MAIN_FIND )) data_byte <= data_out;
- //else data_byte <= data_out;
- end
- // End of the FSM of the SD card reader
- // ------------------------------------------------------------------------
- // ------------------------------------------------------------------------
- // LCD Display function.
- always @(posedge clk) begin
- if (~reset_n) begin
- row_A = "SD card cannot ";
- row_B = "be initialized! ";
- end
- else if (done_flag) begin
- row_A <= {word, word_1, word_2, word_3, word_4, word_5, word_6, word_7, ((p_addr_1[0:7] > 9)? "7" : "0") + p_addr_1[0:7], ((p_addr_1[8:15] > 9)? "7" : "0") + p_addr_1[8:15], ((p_addr_1[16:23] > 9)? "7" : "0") + p_addr_1[16:23], ((p_addr_1[24:31] > 9)? "7" : "0") + p_addr_1[24:31]};
- //row_A <= {word, word_1};
- // row_B <= { "Byte ",
- // sd_counter[9:8] + "0",
- // ((sd_counter[7:4] > 9)? "7" : "0") + sd_counter[7:4],
- // ((sd_counter[3:0] > 9)? "7" : "0") + sd_counter[3:0],
- // "h = ",
- // ((data_byte[7:4] > 9)? "7" : "0") + data_byte[7:4],
- // ((data_byte[3:0] > 9)? "7" : "0") + data_byte[3:0], "h." };
- //row_A <= A_mat[0:127];
- row_B <= B_mat[0:127];
- end
- else if (P == S_MAIN_IDLE) begin
- row_A <= "Hit BTN2 to read";
- row_B <= "the SD card ... ";
- end
- end
- // End of the LCD display function
- // ------------------------------------------------------------------------
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement