1/1

|
ram-on-chip timing
by strug on Nov 18, 2011 |
strug
Posts: 25 Joined: Dec 31, 2009 Last seen: May 9, 2012 |
||
|
In module wb_ram_b3 of orpsocv2, the memory is simulated by the array reg [dw-1:0] mem [ 0 : mem_words-1 ].
I now simulate the memory by the core generator of ISE. There is the difference of timing in the two ways. The adr and wb_dat_o are simultaneous in the former way . In the latter way, There is a clock cycle delay between adr and wb_dat_o,which results in the system crash. |
|||
|
RE: ram-on-chip timing
by strug on Nov 18, 2011 |
strug
Posts: 25 Joined: Dec 31, 2009 Last seen: May 9, 2012 |
||
|
I modified the module ram_wb_b3 as following:"
module ram_wb_b3( wb_adr_i, wb_bte_i, wb_cti_i, wb_cyc_i, wb_dat_i, wb_sel_i, wb_stb_i, wb_we_i, wb_ack_o, wb_err_o, wb_rty_o, wb_dat_o, wb_clk_i, wb_rst_i); parameter dw = 32; parameter aw = 32; input [aw-1:0] wb_adr_i; input [1:0] wb_bte_i; input [2:0] wb_cti_i; input wb_cyc_i; input [dw-1:0] wb_dat_i; input [3:0] wb_sel_i; input wb_stb_i; input wb_we_i; output wb_ack_o; output wb_err_o; output wb_rty_o; output [dw-1:0] wb_dat_o; input wb_clk_i; input wb_rst_i; wire ram_we; // Register to address internal memory array // Memory parameters parameter mem_size_bytes = 32'h0000_5000; // 20KBytes parameter mem_adr_width = 15; //(log2(mem_size_bytes)); parameter bytes_per_dw = (dw/8); parameter adr_width_for_num_word_bytes = 2; //(log2(bytes_per_dw)) parameter mem_words = (mem_size_bytes/bytes_per_dw); // synthesis attribute ram_style of mem is block reg [dw-1:0] mem [ 0 : mem_words-1 ] /* verilator public */ /* synthesis ram_style = no_rw_check */; // Register to address internal memory array reg [(mem_adr_width-adr_width_for_num_word_bytes)-1:0] adr; reg wb_ack_o; assign ram_we = wb_we_i & wb_ack_o; ram_wb_b ram_wb_b_0( .addr (adr), .clk (wb_clk_i), .din (wb_dat_i), .dout (wb_dat_o), .we (ram_we) ); // Address registering logic always@(posedge wb_clk_i) if(wb_rst_i) adr else if (wb_cyc_i & wb_stb_i) adr always @(posedge wb_clk_i) if (wb_cyc_i & wb_stb_i & !wb_ack_o) wb_ack_o else wb_ack_o // Function to access RAM (for use by Verilator). function [31:0] get_mem32; // verilator public input [aw-1:0] addr; get_mem32 = mem[addr]; endfunction // get_mem32 endmodule " The module ram_wb_b is generated by the ISE core generator. However, there is a wrong simulation wave in the attachment.
ram_ip.jpg (82 kb)
|
|||
|
RE: ram-on-chip timing
by strug on Nov 18, 2011 |
strug
Posts: 25 Joined: Dec 31, 2009 Last seen: May 9, 2012 |
||
|
module ram_wb_b(
addr, clk, din, dout, we); input [12 : 0] addr; input clk; input [31 : 0] din; output [31 : 0] dout; input we; // synthesis translate_off BLKMEMSP_V6_2 #( .c_addr_width(13), .c_default_data("0"), .c_depth(6400), .c_enable_rlocs(0), .c_has_default_data(0), .c_has_din(1), .c_has_en(0), .c_has_limit_data_pitch(0), .c_has_nd(0), .c_has_rdy(0), .c_has_rfd(0), .c_has_sinit(0), .c_has_we(1), .c_limit_data_pitch(18), .c_mem_init_file("ram_wb_b.mif"), .c_pipe_stages(0), .c_reg_inputs(0), .c_sinit_value("0"), .c_width(32), .c_write_mode(0), .c_ybottom_addr("0"), .c_yclk_is_rising(1), .c_yen_is_high(1), .c_yhierarchy("hierarchy1"), .c_ymake_bmm(0), .c_yprimitive_type("32kx1"), .c_ysinit_is_high(1), .c_ytop_addr("1024"), .c_yuse_single_primitive(0), .c_ywe_is_high(1), .c_yydisable_warnings(1)) inst ( .ADDR(addr), .CLK(clk), .DIN(din), .DOUT(dout), .WE(we), .EN(), .ND(), .RFD(), .RDY(), .SINIT()); // synthesis translate_on // XST black box declaration // box_type "black_box" // synthesis attribute box_type of ram_wb_b is "black_box" endmodule |
|||
|
RE: ram-on-chip timing
by strug on Nov 18, 2011 |
strug
Posts: 25 Joined: Dec 31, 2009 Last seen: May 9, 2012 |
||
|
module ram_wb_b3(
wb_adr_i, wb_bte_i, wb_cti_i, wb_cyc_i, wb_dat_i, wb_sel_i, wb_stb_i, wb_we_i, wb_ack_o, wb_err_o, wb_rty_o, wb_dat_o, wb_clk_i, wb_rst_i); parameter dw = 32; parameter aw = 32; input [aw-1:0] wb_adr_i; input [1:0] wb_bte_i; input [2:0] wb_cti_i; input wb_cyc_i; input [dw-1:0] wb_dat_i; input [3:0] wb_sel_i; input wb_stb_i; input wb_we_i; output wb_ack_o; output wb_err_o; output wb_rty_o; output [dw-1:0] wb_dat_o; input wb_clk_i; input wb_rst_i; wire ram_we; // Register to address internal memory array // Memory parameters parameter mem_size_bytes = 32'h0000_5000; // 20KBytes parameter mem_adr_width = 15; //(log2(mem_size_bytes)); parameter bytes_per_dw = (dw/8); parameter adr_width_for_num_word_bytes = 2; //(log2(bytes_per_dw)) parameter mem_words = (mem_size_bytes/bytes_per_dw); // synthesis attribute ram_style of mem is block reg [dw-1:0] mem [ 0 : mem_words-1 ] /* verilator public */ /* synthesis ram_style = no_rw_check */; // Register to address internal memory array reg [(mem_adr_width-adr_width_for_num_word_bytes)-1:0] adr; reg wb_ack_o; assign ram_we = wb_we_i & wb_ack_o; ram_wb_b ram_wb_b_0( .addr (adr), .clk (wb_clk_i), .din (wb_dat_i), .dout (wb_dat_o), .we (ram_we) ); // Address registering logic always@(posedge wb_clk_i) if(wb_rst_i) adr else if (wb_cyc_i & wb_stb_i) adr always @(posedge wb_clk_i) if (wb_cyc_i & wb_stb_i & !wb_ack_o) wb_ack_o else wb_ack_o endmodule |
|||
|
RE: ram-on-chip timing
by rfajardo on Nov 18, 2011 |
rfajardo
Posts: 306 Joined: Jun 12, 2008 Last seen: Jan 6, 2020 |
||
|
Hi Strug,
You have to register the acknowledge signal: assign wb_ack_o = ack_re | ack_we; // // Write acknowledge // always @ (negedge wb_clk_i or posedge wb_rst_i) begin if (wb_rst_i) ack_we else if (wb_cyc_i & wb_stb_i & wb_we_i & ~ack_we) ack_we else ack_we end // // read acknowledge // always @ (posedge wb_clk_i or posedge wb_rst_i) begin if (wb_rst_i) ack_re else if (wb_cyc_i & wb_stb_i & ~wb_err_o & ~wb_we_i & ~ack_re) ack_re else ack_re end |
|||
1/1

