I'm working with a Gowin FPGA and they recommend instantiating block RAM. That sounds great, but how do I simulate that? I would expect there to be a library with the model for the instantiation primative, but Gowin provides no simulation resources that I know of. I would happily write code to infer the RAM if I completely understood the details to know I have it right. These buggers have some tricky behavior in the read after write situation. The "semi-dual port" mode only has one option for that, "normal" mode which seems to have a delay for turning around the direction of the write port to read. But semi-dual port has a write port and a separate read port (meaning the one port read mode is not used and the other port write mode is not used) so how can there be a limitation on the read when writing on a separate port??? I probably need to read the description again until it all sinks in.
Until then, is it customary for the FPGA vendor to supply a simulation library for their instantiated FPGA components?
Synth guide https://www.gowinsemi.com/upload/database_doc/762/document/5f7426a6bf224.pdf
B-SRAM & S-SRAM User Guide https://www.gowinsemi.com/upload/database_doc/1232/document/5f7befe0a7c86.pdf
You will need to create a user account to login before you can access the docs.
1 Answer 1
My opinion? Don't instantiate. Infer wherever you possibly can.
Find out how your synth tool infers BRAM and write memory that it can translate into BRAM. (It's just an array; you may need to clock the address and/or data to make it synchronous). Semi-dual port ... limitation on read may only apply when concurrently writing to the same address? Link to the datasheet if in doubt. There should also be a "synthesis style guide" to help.
Mock up a simple testcase and synth it to see if you get the usage you expect.
-
1\$\begingroup\$ Your advice sounds great, but not useful. I'd have thought it was obvious that I'd much prefer to infer the BRAM. If a vendor advises to instantiate memory, I'm forced to expect it's for a reason. Then there's the matter of the data sheet not being very clear about the specific details of how the block ram behaves in this mode and the style guide is even worse showing an async write to the addressed location when the "rst" signal is asserted. \$\endgroup\$gnuarm– gnuarm2020年10月22日 17:57:59 +00:00Commented Oct 22, 2020 at 17:57
-
\$\begingroup\$ Here's Verilog for semi-dual-port BRAM. I'm no expert in Verilog, but won't if(ce |wre) OR and not AND the two? I've not seen rst on BRAM since xc4000.
module read_first_wp_pre_1(data_out, data_in, waddr, raddr,clk, rst,ce, wre); output [10:0]data_out; input [10:0]data_in; input [6:0]raddr,waddr; input clk, rst,ce, wre; reg [10:0] mem [127:0]; reg [10:0] data_out; always@(posedge clk) if(ce |wre) data_out <= mem[raddr]; always @(posedge clk) if (rst) mem[waddr] <= data_in; else if (ce | !wre) mem[waddr] <= data_in; endmodule
\$\endgroup\$gnuarm– gnuarm2020年10月22日 18:08:16 +00:00Commented Oct 22, 2020 at 18:08 -
\$\begingroup\$ Formatting in comments sucks. You can view this in the style guide. \$\endgroup\$gnuarm– gnuarm2020年10月22日 18:16:34 +00:00Commented Oct 22, 2020 at 18:16
-
\$\begingroup\$ That's example 6 which appears to contradict its own Fig 4-13 : I believe the write on RST is a copy/pasto in the Verilog and RST should just clear the output reg like every other example. As their BRAM user guide says. Take that up with gowin tech support. They clearly support inference so I'll stand by my answer; but if you still want to instantiate, you'll either have to find their simulation library 9they MUST surely have one!) or write your own to match the description. \$\endgroup\$user16324– user163242020年10月22日 18:46:49 +00:00Commented Oct 22, 2020 at 18:46
-
\$\begingroup\$ Sorry, I don't get your basis for saying they "support" inference... or more importantly, how to write the code for inference. Their documentation is inconsistent and erroneous. I can't believe even their description of how the BRAM works. I suppose I can fall back on the long valued and ever trusted method we call, trial and error. In other words, keep futzing with the code until it works. \$\endgroup\$gnuarm– gnuarm2020年10月24日 00:52:35 +00:00Commented Oct 24, 2020 at 0:52