Date de création 2020-08-06Date d’expiration 2020-11-07module serial_ram ( input wire clk24, input wire rx, output wire tx ); // Definitions to make code easier to read and understand. localparam HIGH = 1'b1, LOW = 1'b0, TRUE = HIGH, FALSE = LOW, TRUE_n = LOW, FALSE_n = HIGH; localparam CLK_FREQUENCY_HZ = 132_000_000, SERIAL_BPS = 460_800; reg fake_reset = TRUE; reg fake_resetn = TRUE_n; always @(posedge clk24) begin fake_reset <= FALSE; fake_resetn <= FALSE_n; end wire clk; clk50 clk132 ( .refclk (clk24), .reset (fake_reset), .clk0_out (clk) ); // Serial data coming in wire [7:0] data_in; wire oe; serial_in #( .CLK_FREQUENCY_HZ (CLK_FREQUENCY_HZ), .SERIAL_BPS (SERIAL_BPS) ) serial_in ( .clk (clk), .reset (fake_reset), .rx (rx), .data (data_in), .oe (oe) ); // Serial data coming out reg ie = FALSE; reg [7:0] data_out; wire sending; serial_out #( .CLK_FREQUENCY_HZ (CLK_FREQUENCY_HZ), .SERIAL_BPS (SERIAL_BPS) ) serial_out ( .clk (clk), .reset (fake_reset), .ie (ie), .data (data_out), .tx (tx), .sending (sending) ); // SDRAM memory reg [22:0] rd_addr; reg [22:0] wr_addr; reg rd_enable; reg wr_enable; wire rd_ready; wire [31:0] rd_data; reg [31:0] wr_data; reg [3:0] wr_mask; ram ram ( .clk (clk), .rst_n (fake_resetn), .wr_address (wr_addr), .wr_data (wr_data), .wr_request (wr_enable), .wr_mask (wr_mask), .rd_address (rd_addr), .rd_data (rd_data), .rd_available (rd_ready), .rd_request (rd_enable) ); reg [7:0] f_in = 'd0; reg f_re = FALSE; reg f_we = FALSE; wire [7:0] f_out; wire empty; fifo_out fifo_out ( .rst (fake_reset), .di (f_in), .clkr (clk), .re (f_re), .clkw (clk), .we (f_we), .do (f_out), .empty_flag (empty), .full_flag (), .rdusedw (), .wrusedw () ); // Automaton localparam CMD_INIT = 8'h2E, // . CMD_SET = 8'h73, // s CMD_GET = 8'h67; // g reg [31:0] queue = 32'h00_00_00_00; reg [1:0] read_address; always @(posedge clk) if (oe) case (data_in) CMD_INIT: begin queue <= 32'h00_00_00_00; rd_enable <= FALSE; wr_enable <= FALSE; wr_mask <= 4'b0000; end CMD_SET: begin wr_addr <= { 8'h00, queue[31:8] }; case (queue[9:8]) 'd0: wr_mask <= 4'b0001; 'd1: wr_mask <= 4'b0010; 'd2: wr_mask <= 4'b0100; 'd3: wr_mask <= 4'b1000; endcase wr_data <= { queue[7:0], queue[7:0] ,queue[7:0], queue[7:0] }; wr_enable <= TRUE; end CMD_GET: begin wr_mask <= 4'b0000; read_address <= queue[1:0]; rd_addr <= queue[20:0]; rd_enable <= TRUE; end default: if (data_in[7:4] == 4'h3) queue <= { queue[27:0], data_in[3:0] }; else queue <= { queue[27:0], data_in[3:0] + 4'h9 }; endcase else begin rd_enable <= FALSE; wr_enable <= FALSE; end // Send anything going out of SDRAM to the FIFO. always @(posedge clk) if (rd_ready && !f_we) begin case (read_address) 'd0: f_in <= rd_data[7:0]; 'd1: f_in <= rd_data[15:8]; 'd2: f_in <= rd_data[23:16]; 'd3: f_in <= rd_data[31:24]; endcase f_we <= TRUE; end else f_we <= FALSE; // Get everything from the FIFO and output it on the serial port. always @(posedge clk) if (!sending && !ie && !empty) begin f_re <= TRUE; data_out <= f_out; ie <= TRUE; end else begin f_re <= FALSE; ie <= FALSE; end endmodule