2022年SDRAM程序代码 .pdf
module sdram_input_efifo_module ( / inputs: clk, rd, reset_n, wr, wr_data, / outputs: almost_empty, almost_full, empty, full, rd_data ) ; output almost_empty; output almost_full; output empty; output full; output 43: 0 rd_data; input clk; input rd; input reset_n; input wr; input 43: 0 wr_data; wire almost_empty; wire almost_full; wire empty; reg 1: 0 entries; reg 43: 0 entry_0; reg 43: 0 entry_1; wire full; reg rd_address; reg 43: 0 rd_data; wire 1: 0 rdwr; reg wr_address; assign rdwr = rd, wr; assign full = entries = 2; assign almost_full = entries = 1; assign empty = entries = 0; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 21 页 - - - - - - - - - assign almost_empty = entries = 1; always (entry_0 or entry_1 or rd_address) begin case (rd_address) / synthesis parallel_case full_case 1d0: begin rd_data = entry_0; end / 1d0 1d1: begin rd_data = entry_1; end / 1d1 default: begin end / default endcase / rd_address end always (posedge clk or negedge reset_n) begin if (reset_n = 0) begin wr_address = 0; rd_address = 0; entries = 0; end else case (rdwr) / synthesis parallel_case full_case 2d1: begin / Write data if (!full) begin entries = entries + 1; wr_address = (wr_address = 1) ? 0 : (wr_address + 1); end end / 2d1 2d2: begin / Read data if (!empty) begin entries = entries - 1; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 21 页 - - - - - - - - - rd_address = (rd_address = 1) ? 0 : (rd_address + 1); end end / 2d2 2d3: begin wr_address = (wr_address = 1) ? 0 : (wr_address + 1); rd_address = (rd_address = 1) ? 0 : (rd_address + 1); end / 2d3 default: begin end / default endcase / rdwr end always (posedge clk) begin /Write data if (wr & !full) case (wr_address) / synthesis parallel_case full_case 1d0: begin entry_0 = wr_data; end / 1d0 1d1: begin entry_1 = wr_data; end / 1d1 default: begin end / default endcase / wr_address end endmodule module sdram ( / inputs: az_addr, az_be_n, az_cs, az_data, az_rd_n, 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 21 页 - - - - - - - - - az_wr_n, clk, reset_n, / outputs: za_data, za_valid, za_waitrequest, zs_addr, zs_ba, zs_cas_n, zs_cke, zs_cs_n, zs_dq, zs_dqm, zs_ras_n, zs_we_n ) ; output 15: 0 za_data; output za_valid; output za_waitrequest; output 12: 0 zs_addr; output 1: 0 zs_ba; output zs_cas_n; output zs_cke; output 1: 0 zs_cs_n; inout 15: 0 zs_dq; output 1: 0 zs_dqm; output zs_ras_n; output zs_we_n; input 24: 0 az_addr; input 1: 0 az_be_n; input az_cs; input 15: 0 az_data; input az_rd_n; input az_wr_n; input clk; input reset_n; wire 23: 0 CODE; reg ack_refresh_request; reg 23: 0 active_addr; wire 1: 0 active_bank; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 21 页 - - - - - - - - - reg active_cs_n; reg 15: 0 active_data; reg 1: 0 active_dqm; reg active_rnw; wire almost_empty; wire almost_full; wire bank_match; wire 8: 0 cas_addr; wire clk_en; wire 4: 0 cmd_all; wire 2: 0 cmd_code; wire cs_n; wire 1: 0 csn_decode; wire csn_match; wire 23: 0 f_addr; wire 1: 0 f_bank; wire f_cs_n; wire 15: 0 f_data; wire 1: 0 f_dqm; wire f_empty; reg f_pop; wire f_rnw; wire f_select; wire 43: 0 fifo_read_data; reg 12: 0 i_addr; reg 4: 0 i_cmd; reg 2: 0 i_count; reg 2: 0 i_next; reg 2: 0 i_refs; reg 2: 0 i_state; reg init_done; reg 12: 0 m_addr; reg 1: 0 m_bank; reg 4: 0 m_cmd; reg 2: 0 m_count; reg 15: 0 m_data; reg 1: 0 m_dqm; reg 8: 0 m_next; reg 8: 0 m_state; reg oe; wire pending; wire rd_strobe; reg 2: 0 rd_valid; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 21 页 - - - - - - - - - reg 12: 0 refresh_counter; reg refresh_request; wire rnw_match; wire row_match; wire 23: 0 txt_code; reg za_cannotrefresh; reg 15: 0 za_data; reg za_valid; wire za_waitrequest; wire 12: 0 zs_addr; wire 1: 0 zs_ba; wire zs_cas_n; wire zs_cke; wire 1: 0 zs_cs_n; wire 15: 0 zs_dq; wire 1: 0 zs_dqm; wire zs_ras_n; wire zs_we_n; assign clk_en = 1; /s1, which is an e_avalon_slave assign zs_cs_n, zs_ras_n, zs_cas_n, zs_we_n = m_cmd; assign zs_addr = m_addr; assign zs_cke = clk_en; assign zs_dq = oe?m_data:161bz; assign zs_dqm = m_dqm; assign zs_ba = m_bank; assign f_select = f_pop & pending; assign f_rnw, f_cs_n, f_addr, f_dqm, f_data = fifo_read_data; assign cs_n = f_select ? f_cs_n : active_cs_n; assign csn_decode0 = cs_n != 1h0; assign csn_decode1 = cs_n != 1h1; sdram_input_efifo_module the_sdram_input_efifo_module ( .almost_empty (almost_empty), .almost_full (almost_full), .clk (clk), .empty (f_empty), .full (za_waitrequest), .rd (f_select), .rd_data (fifo_read_data), .reset_n (reset_n), .wr (az_wr_n | az_rd_n) & !za_waitrequest), .wr_data (az_wr_n, az_addr, az_wr_n ? 2b0 : az_be_n, az_data) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 21 页 - - - - - - - - - ); assign f_bank = f_addr23,f_addr9; / Refresh/init counter. always (posedge clk or negedge reset_n) begin if (reset_n = 0) refresh_counter = 7500; else if (refresh_counter = 0) refresh_counter = 1171; else refresh_counter = refresh_counter - 1b1; end / Refresh request signal. always (posedge clk or negedge reset_n) begin if (reset_n = 0) refresh_request = 0; else if (1) refresh_request = (refresh_counter = 0) | refresh_request) & ack_refresh_request & init_done; end / Generate an Interrupt if two ref_reqs occur before one ack_refresh_request always (posedge clk or negedge reset_n) begin if (reset_n = 0) za_cannotrefresh = 0; else if (1) za_cannotrefresh = (refresh_counter = 0) & refresh_request; end / Initialization-done flag. always (posedge clk or negedge reset_n) begin if (reset_n = 0) init_done = 0; else if (1) init_done = init_done | (i_state = 3b101); end / * Init FSM * 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 21 页 - - - - - - - - - always (posedge clk or negedge reset_n) begin if (reset_n = 0) begin i_state = 3b000; i_next = 3b000; i_cmd = 5b11111; i_addr = 131b1; i_count = 31b0; end else begin i_addr = 131b1; case (i_state) / synthesis parallel_case full_case 3b000: begin i_cmd = 5b11111; i_refs = 3b0; /Wait for refresh count-down after reset if (refresh_counter = 0) i_state = 3b001; end / 3b000 3b001: begin i_state = 3b011; i_cmd = 21b0,3h2; i_count = 1; i_next = 3b010; end / 3b001 3b010: begin i_cmd = 21b0,3h1; i_refs = i_refs + 1b1; i_state = 3b011; i_count = 5; / Count up init_refresh_commands if (i_refs = 3h1) i_next = 3b111; else i_next = 3b010; end / 3b010 3b011: begin i_cmd 1) i_count = i_count - 1b1; else i_state = i_next; end / 3b011 3b101: begin i_state = 3b101; end / 3b101 3b111: begin i_state = 3b011; i_cmd = 21b0,3h0; i_addr = 31b0,1b0,2b00,3h3,4h0; i_count = 4; i_next = 3b101; end / 3b111 default: begin i_state = 3b000; end / default endcase / i_state endcase / i_state end end assign active_bank = active_addr23,active_addr9; assign csn_match = active_cs_n = f_cs_n; assign rnw_match = active_rnw = f_rnw; assign bank_match = active_bank = f_bank; assign row_match = active_addr22 : 10 = f_addr22 : 10; assign pending = csn_match & rnw_match & bank_match & row_match & !f_empty; assign cas_addr = f_select ? 41b0,f_addr8 : 0 : 41b0,active_addr8 : 0 ; / * Main FSM * always (posedge clk or negedge reset_n) begin if (reset_n = 0) begin m_state = 9b000000001; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 21 页 - - - - - - - - - m_next = 9b000000001; m_cmd = 5b11111; m_bank = 2b00; m_addr = 13b0000000000000; m_data = 16b0000000000000000; m_dqm = 2b00; m_count = 3b000; ack_refresh_request = 1b0; f_pop = 1b0; oe = 1b0; end else begin f_pop = 1b0; oe = 1b0; case (m_state) / synthesis parallel_case full_case 9b000000001: begin /Wait for init-fsm to be done. if (init_done) begin /Hold bus if another cycle ended to arf. if (refresh_request) m_cmd = 21b0,3h7; else m_cmd = 5b11111; ack_refresh_request = 1b0; /Wait for a read/write request. if (refresh_request) begin m_state = 9b001000000; m_next = 9b010000000; m_count = 1; active_cs_n = 11b1; end else if (!f_empty) begin f_pop = 1b1; active_cs_n = f_cs_n; active_rnw = f_rnw; active_addr = f_addr; active_data = f_data; active_dqm = f_dqm; m_state = 9b000000010; end 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 21 页 - - - - - - - - - end else begin m_addr = i_addr; m_state = 9b000000001; m_next = 9b000000001; m_cmd = i_cmd; end end / 9b000000001 9b000000010: begin m_state = 9b000000100; m_cmd = csn_decode,3h3; m_bank = active_bank; m_addr = active_addr22 : 10; m_data = active_data; m_dqm = active_dqm; m_count = 2; m_next = active_rnw ? 9b000001000 : 9b000010000; end / 9b000000010 9b000000100: begin / precharge all if arf, else precharge csn_decode if (m_next = 9b010000000) m_cmd = 21b0,3h7; else m_cmd 1) m_count = m_count - 1b1; else m_state = m_next; end / 9b000000100 9b000001000: begin m_cmd = csn_decode,3h5; m_bank = f_select ? f_bank : active_bank; m_dqm = f_select ? f_dqm : active_dqm; m_addr = cas_addr; /Do we have a transaction pending? if (pending) begin /if we need to ARF, bail, else spin if (refresh_request) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 21 页 - - - - - - - - - begin m_state = 9b000000100; m_next = 9b000000001; m_count = 2; end else begin f_pop = 1b1; active_cs_n = f_cs_n; active_rnw = f_rnw; active_addr = f_addr; active_data = f_data; active_dqm = f_dqm; end end else begin /correctly end RD spin cycle if fifo mt if (pending & f_pop) m_cmd = csn_decode,3h7; m_state = 9b100000000; end end / 9b000001000 9b000010000: begin m_cmd = csn_decode,3h4; oe = 1b1; m_data = f_select ? f_data : active_data; m_dqm = f_select ? f_dqm : active_dqm; m_bank = f_select ? f_bank : active_bank; m_addr = cas_addr; /Do we have a transaction pending? if (pending) begin /if we need to ARF, bail, else spin if (refresh_request) begin m_state = 9b000000100; m_next = 9b000000001; m_count = 2; end else begin f_pop = 1b1; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 12 页,共 21 页 - - - - - - - - - active_cs_n = f_cs_n; active_rnw = f_rnw; active_addr = f_addr; active_data = f_data; active_dqm = f_dqm; end end else begin /correctly end WR spin cycle if fifo empty if (pending & f_pop) begin m_cmd = csn_decode,3h7; oe = 1b0; end m_state = 9b100000000; end end / 9b000010000 9b000100000: begin m_cmd 1) m_count = m_count - 1b1; else begin m_state = 9b001000000; m_count = 1; end end / 9b000100000 9b001000000: begin m_state = 9b000000100; m_addr = 131b1; / precharge all if arf, else precharge csn_decode if (refresh_request) m_cmd = 21b0,3h2; else m_cmd = csn_decode,3h2; end / 9b001000000 9b010000000: begin ack_refresh_request = 1b1; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 13 页,共 21 页 - - - - - - - - - m_state = 9b000000100; m_cmd = 21b0,3h1; m_count = 5; m_next = 9b000000001; end / 9b010000000 9b100000000: begin m_cmd = csn_decode,3h7; /if we need to ARF, bail, else spin if (refresh_request) begin m_state = 9b000000100; m_next = 9b000000001; m_count = 1; end else /wait for fifo to have contents if (!f_empty) /Are we pending yet? if (csn_match & rnw_match & bank_match & row_match) begin m_state = f_rnw ? 9b000001000 : 9b000010000; f_pop = 1b1; active_cs_n = f_cs_n; active_rnw = f_rnw; active_addr = f_addr; active_data = f_data; active_dqm = f_dqm; end else begin m_state = 9b000100000; m_next = 9b000000001; m_count = 1; end end / 9b100000000 / synthesis translate_off default: begin m_state = m_state; m_cmd = 5b11111; f_pop = 1b0; oe = 1b0; end / default 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 14 页,共 21 页 - - - - - - - - - / synthesis translate_on endcase / m_state end end assign rd_strobe = m_cmd2 : 0 = 3h5; /Track RD Reqs based on cas_latency w/shift reg always (posedge clk or negedge reset_n) begin if (reset_n = 0) rd_valid = 31b0; else rd_valid = (rd_valid 1) | 21b0, rd_strobe ; end / Register dq data. always (posedge clk or negedge reset_n) begin if (reset_n = 0) za_data = 0; else if (1) za_data = zs_dq; end / Delay za_valid to match registered data. always (posedge clk or negedge reset_n) begin if (reset_n = 0) za_valid = 0; else if (1) za_valid = rd_valid2; end assign cmd_code = m_cmd2 : 0; assign cmd_all = m_cmd; assign txt_code = (cmd_code = 3h0)? 24h4c4d52 : (cmd_code = 3h1)? 24h415246 : (cmd_code = 3h2)? 24h505245 : (cmd_code = 3h3)? 24h414354 : (cmd_code = 3h4)? 24h205752 : (cmd_code = 3h5)? 24h205244 : 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 15 页,共 21 页 - - - - - - - - - (cmd_code = 3h6)? 24h425354 : (cmd_code = 3h7)? 24h4e4f50 : 24h424144; assign CODE = &(cmd_all|5h7) ? 24h494e48 : txt_code; endmodule /RAM 模型module sdram_test_component_ram_module ( / inputs: data, rdaddress, rdclken, wraddress, wrclock, wren, / outputs: q ) ; output 15: 0 q; input 15: 0 data; input 24: 0 rdaddress; input rdclken; input 24: 0 wraddress; input wrclock; input wren; reg 15: 0 mem_array 33554431: 0; wire 15: 0 q; reg 24: 0 read_address; /synthesis translate_off / SIMULATION-ONLY CONTENTS always (rdaddress) begin if (1) read_address = rdaddress; end 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 16 页,共 21 页 - - - - - - - - - / Data read is asynchronous. assign q = mem_arrayread_address; initial $readmemh(sdram.dat, mem_array); always (posedge wrclock) begin / Write data if (wren) mem_arraywraddress = data; end endmodule module sdram_test_component ( / inputs: clk, zs_addr, zs_ba, zs_cas_n, zs_cke, zs_cs_n, zs_dqm, zs_ras_n, zs_we_n, / outputs: zs_dq ) ; inout 15: 0 zs_dq; input clk; input 12: 0 zs_addr; input 1: 0 zs_ba; input zs_cas_n; input zs_cke; input 1: 0 zs_cs_n; input 1: 0 zs_dqm; input zs_ras_n; input zs_we_n; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 17 页,共 21 页 - - - - - - - - - wire 23: 0 CODE; wire 12: 0 a; wire 8: 0 addr_col; reg 15: 0 addr_crb; wire 1: 0 ba; wire cas_n; wire cke; wire 2: 0 cmd_code; wire 1: 0 cs; reg cs_encode; wire 1: 0 cs_n; wire 1: 0 dqm; wire 2: 0 index; reg 2: 0 latency; wire 1: 0 mask; wire 15: 0 mem_bytes; wire ras_n; reg 24: 0 rd_addr_pipe_0; reg 24: 0 rd_addr_pipe_1; reg 24: 0 rd_addr_pipe_2; reg 1: 0 rd_mask_pipe_0; reg 1: 0 rd_mask_pipe_1; reg 1: 0 rd_mask_pipe_2; reg 2: 0 rd_valid_pipe; wire 24: 0 read_addr; wire 15: 0 read_data; wire 1: 0 read_mask; wire 15: 0 read_temp; wire read_valid; wire 15: 0 rmw_temp; wire 24: 0 test_addr; wire 23: 0 txt_code; wire we_n; wire 15: 0 zs_dq; initial begin $write(n); $write(*n); $write(This testbench includes an SOPC Builder Generated Altera model:n); $write(sdram_test_component.v, to simulate accesses to SDRAM.n); $write(Initial contents are loaded from the file: sdram.dat.n); $write(*n); end 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 18 页,共 21 页 - - - - - - - - - /Synchronous write when (CODE = 24h2