Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- `timescale 1ns / 1ps
- module mid(
- input clk,
- input reset_n,
- input [3:0] usr_btn,
- output [3:0] usr_led,
- input uart_rx,
- output uart_tx,
- // 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 [2:0] S_MAIN_INIT = 0, S_MAIN_WAIT= 4,
- S_MAIN_REPLY = 6;
- localparam [1:0] S_UART_IDLE = 0, S_UART_WAIT = 1,
- S_UART_SEND = 2, S_UART_INCR = 3;
- // declare text message parameters
- localparam MSG3_SIZE = 139;
- localparam MEM_SIZE = 139;
- localparam PROMPT1_STR = 0;
- localparam REPLY_STR = 0;
- localparam INIT_DELAY = 100_000; // 1 msec @ 100 MHz
- // declare system variables
- wire enter_pressed;
- wire print_enable, print_done;
- reg [$clog2(MEM_SIZE):0] send_counter;
- reg [2:0] P, P_next;
- reg [1:0] Q, Q_next;
- reg [$clog2(INIT_DELAY):0] init_counter;
- reg [7:0] data[0:MEM_SIZE-1];
- reg [0:MSG3_SIZE*8-1] msg3 = { "The result is:\015\012[ 11CE9, 18749, 0EE26, 16F64 ]",
- "\015\012[ 58415, 7579, 04446, 55564 ]",
- "\015\012[ 666E9, 77749, 88886, 99964 ]",
- "\015\012[ AAAE9, BBB49, CCC26, DDD64 ]",8'h00 };
- reg [15:0] num_reg; // The keyin number register
- reg [2:0] key_cnt;
- reg [15:0] num1, num2, tmp1, tmp2;
- reg [15:0] gcd;
- reg gcd_done;
- // declare UART signals
- wire transmit;
- wire received;
- wire [7:0] rx_byte;
- reg [7:0] rx_temp;
- wire [7:0] tx_byte;
- wire is_receiving;
- wire is_transmitting;
- wire recv_error;
- reg sram_ok,uart_ok;
- /* The UART device takes a 100MHz clock to handle I/O at 9600 baudrate */
- uart uart0(
- .clk(clk),
- .rst(~reset_n),
- .rx(uart_rx),
- .tx(uart_tx),
- .transmit(transmit),
- .tx_byte(tx_byte),
- .received(received),
- .rx_byte(rx_byte),
- .is_receiving(is_receiving),
- .is_transmitting(is_transmitting),
- .recv_error(recv_error)
- );
- integer idx;
- //////////////////////// sd card ///////////////////////////////////////////////
- localparam [2:0] S_MAIN_INIT6 = 3'b000, S_MAIN_IDLE6 = 3'b001,
- S_MAIN_WAIT6 = 3'b010, S_MAIN_READ6 = 3'b011,
- S_MAIN_DONE6 = 3'b100, S_MAIN_SHOW6 = 3'b101,
- S_MAIN_CALC6 = 3'b110, S_MAIN_MULT6 = 3'b111;
- // Declare system variables
- wire btn_level, btn_pressed;
- reg prev_btn_level;
- reg [2:0] K, K_next;
- reg [9:0] sd_counter;
- reg [7:0] data_byte;
- reg [31:0] blk_addr;
- reg [127:0] row_A = "SD card cannot ";
- reg [127:0] row_B = "be initialized! ";
- reg done_flag; // Signals the completion of reading one SD sector.
- // 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;
- // 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;
- reg [0:63] start_line = "MATX_TAG";
- reg [0:63] end_line = "DLAB_END";
- reg [0:31] the = " the";
- assign clk_sel = (init_finished)? clk : clk_500k; // clock for the SD controller
- assign usr_led = K;
- reg[1:0] find_head,find_tail;
- reg[4:0] head_index;
- //reg[0:31] data;
- reg[0:255] A,B;
- //reg[0:287] C; ///////////////////tem
- reg[0:15] mat_index;
- 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)
- );
- 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)
- );
- 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)
- );
- 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;
- 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.
- always @(posedge clk) begin
- if (~reset_n) begin
- K <= S_MAIN_INIT6;
- done_flag <= 0;
- end
- else begin
- K <= K_next;
- if (K == S_MAIN_DONE6)
- done_flag <= 1;
- else if (K == S_MAIN_SHOW6 && K_next == S_MAIN_IDLE6)
- done_flag <= 0;
- else
- done_flag <= done_flag;
- end
- end
- always @(*) begin // FSM next-state logic
- case (K)
- S_MAIN_INIT6: // wait for SD card initialization
- if (init_finished == 1) K_next = S_MAIN_IDLE6;
- else K_next = S_MAIN_INIT6;
- S_MAIN_IDLE6: // wait for button click
- if (btn_pressed == 1) K_next = S_MAIN_WAIT6;
- else K_next = S_MAIN_IDLE6;
- S_MAIN_WAIT6: // issue a rd_req to the SD controller until it's ready
- K_next = S_MAIN_READ6;
- S_MAIN_READ6: // wait for the input data to enter the SRAM buffer
- if (sd_counter == 512) K_next = S_MAIN_DONE6;
- else K_next = S_MAIN_READ6;
- S_MAIN_DONE6: // read byte 0 of the superblock from sram[]
- K_next = S_MAIN_CALC6;
- S_MAIN_CALC6:
- if (sram_ok) K_next = S_MAIN_MULT6;
- else if (sd_counter == 512) K_next = S_MAIN_WAIT6;
- else K_next = S_MAIN_CALC6;
- S_MAIN_MULT6:
- //if(uart_ok) K_next = S_MAIN_SHOW6;
- K_next = S_MAIN_SHOW6;
- //else K_next = S_MAIN_MULT6;
- S_MAIN_SHOW6:
- if(print_done) K_next = S_MAIN_IDLE6;
- else K_next = S_MAIN_SHOW6;
- default:
- K_next = S_MAIN_IDLE6;
- endcase
- end
- always @(posedge clk) begin
- if (~reset_n) begin
- find_head = 0;
- head_index = 0;
- A = 0; B = 0; //C = 0;
- mat_index = 0;
- sram_ok = 0;
- end
- else begin
- if(K == S_MAIN_CALC6 && sd_counter < 512) begin
- if(find_head == 1) begin
- if((data_byte >= 48 && data_byte <= 57) ||(data_byte >= 65 && data_byte <= 70)) begin
- if(mat_index >= 256)
- sram_ok = 1;
- else if(mat_index < 127) begin
- A[mat_index +:4] = (data_byte >= "A") ? data_byte - "7" : data_byte - "0" ;
- mat_index = mat_index + 4;
- end
- else if(mat_index >= 128) begin
- B[mat_index - 128 +:4] = (data_byte >= "A") ? data_byte - "7" : data_byte - "0" ;
- mat_index = mat_index + 4;
- end
- end
- end
- else begin
- if(head_index >= 8) begin
- find_head = 1;
- head_index = 0;
- end
- else begin
- if(data_byte != start_line[head_index*8 +:8])
- head_index = 0;
- else
- head_index = head_index + 1;
- end
- end
- end
- end
- end
- // FSM output logic: controls the 'rd_req' and 'rd_addr' signals.
- always @(*) begin
- rd_req = (K == S_MAIN_WAIT6);
- rd_addr = blk_addr;
- end
- always @(posedge clk) begin
- if (~reset_n) blk_addr <= 32'h2000;
- else if(K == S_MAIN_CALC6 && K_next == S_MAIN_WAIT6)
- blk_addr = blk_addr + 1;
- end
- // FSM output logic: controls the 'sd_counter' signal.
- // SD card read address incrementer
- always @(posedge clk) begin
- if (~reset_n || (K == S_MAIN_READ6 && K_next == S_MAIN_DONE6) || (K == S_MAIN_CALC6 && K_next == S_MAIN_WAIT6))
- sd_counter <= 0;
- else if ((K == S_MAIN_READ6 && sd_valid) ||
- (K == S_MAIN_CALC6) )
- 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 (K == S_MAIN_DONE6 || K == S_MAIN_CALC6) data_byte <= data_out;
- end
- always @(posedge clk) begin
- if (~reset_n) begin
- row_A = "SD card cannot ";
- row_B = "be initialized! ";
- end
- else if (K == S_MAIN_IDLE6) begin
- row_A <= "Hit BTN2 to read";
- row_B <= "the SD card ... ";
- end
- /*else if(K == S_MAIN_SHOW6) begin
- row_A <= {A[0:127]};
- row_B <= {B[0:127]};
- end*/
- end
- ///////////////////////// uart ///////////////////////////////////////////
- // Combinational I/O logics
- assign enter_pressed = (rx_temp == 8'h0D);
- // Main FSM that reads the UART input, compute GCD, and
- // print the output of the GCD.
- always @(posedge clk) begin
- if (~reset_n) P <= S_MAIN_INIT;
- else P <= P_next;
- end
- always @(*) begin // FSM next-state logic
- case (P)
- S_MAIN_INIT: // Wait for initial delay of the circuit.
- if (init_counter < INIT_DELAY) P_next = S_MAIN_INIT;
- else P_next = S_MAIN_WAIT;
- S_MAIN_WAIT: // wait for <Enter> key.
- if (K == S_MAIN_SHOW6) P_next = S_MAIN_REPLY;
- else P_next = S_MAIN_WAIT;
- S_MAIN_REPLY: // Print the reply message.
- if (print_done) P_next = S_MAIN_INIT;
- else P_next = S_MAIN_REPLY;
- default:
- P_next = S_MAIN_INIT;
- endcase
- end
- // FSM output logics: print string control signals.
- assign print_enable = (P == S_MAIN_WAIT && P_next == S_MAIN_REPLY);
- assign print_done = (tx_byte == 8'h00);
- // Initialization counter.
- always @(posedge clk) begin
- if (P == S_MAIN_INIT) init_counter <= init_counter + 1;
- else init_counter <= 0;
- end
- // End of the FSM of the print string controller
- // ------------------------------------------------------------------------
- // ------------------------------------------------------------------------
- // FSM of the controller to send a string to the UART.
- always @(posedge clk) begin
- if (~reset_n) Q <= S_UART_IDLE;
- else Q <= Q_next;
- end
- always @(*) begin // FSM next-state logic
- case (Q)
- S_UART_IDLE: // wait for the print_string flag
- if (print_enable) Q_next = S_UART_WAIT;
- else Q_next = S_UART_IDLE;
- S_UART_WAIT: // wait for the transmission of current data byte begins
- if (is_transmitting == 1) Q_next = S_UART_SEND;
- else Q_next = S_UART_WAIT;
- S_UART_SEND: // wait for the transmission of current data byte finishes
- if (is_transmitting == 0) Q_next = S_UART_INCR; // transmit next character
- else Q_next = S_UART_SEND;
- S_UART_INCR:
- if (tx_byte == 8'h00) Q_next = S_UART_IDLE; // string transmission ends
- else Q_next = S_UART_WAIT;
- endcase
- end
- // FSM output logics
- assign transmit = (Q_next == S_UART_WAIT || print_enable);
- assign tx_byte = data[send_counter];
- // UART send_counter control circuit
- always @(posedge clk) begin
- case (P_next)
- S_MAIN_INIT: send_counter <= 0;
- default: send_counter <= send_counter + (Q_next == S_UART_INCR);
- endcase
- end
- always @(posedge clk) begin
- rx_temp <= (received)? rx_byte : 8'h0;
- end
- always @(posedge clk) begin
- if (~reset_n)
- for (idx = 0; idx < MSG3_SIZE; idx = idx + 1) data[idx] = msg3[idx*8 +: 8];
- end
- // End of the GCD computation logic
- // ------------------------------------------------------------------------
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement