Thread: [myhdl-list] Describing a rom for Altera Quartus
Brought to you by:
jandecaluwe
From: Frederik T. <sp...@ne...> - 2012-03-27 15:00:03
|
Hello all together, I have a problem with a rom that holds precalculated twiddle factors for a r2²sdf-pipeline-fft. I took the rom from the examples directory and changed it and changed it: def twiddlerom(doutr, douti, addr, N, bitwidth): ''' A rom that holds twiddle factors for a FFT doutr, douti-- data out, real and imaginary addr -- address N -- Number of twiddles Append: attribute romstyle : string; attribute romstyle of tmp : signal is "M9K"; ''' LMAX = 2**(bitwidth-1) MMAX = 2**(2*bitwidth) def getTwiddles(N): ret = [ ... ] # ... return tuple(ret) tmpcontent = getTwiddles(N) ram = tmpcontent tmp = Signal(intbv(0, min=-MMAX, max=MMAX)[2*bitwidth:]) @always_comb def read(): tmp.next = ram[int(addr)] @always_comb def devide(): doutr.next = tmp[2*bitwidth:bitwidth].signed() douti.next = tmp[bitwidth:0].signed() return read, devide The rom holds complex twiddles that are devided in the devide generator. If I just output single values the mentioned problem doesnt' disappear. Simulation works and Xilinx ISE compiles it into a rom. But Quartus uses logic blocks until I add the following lines into the generated VHDL code: attribute romstyle : string; attribute romstyle of q : signal is "M9K"; My questions are if there is a way to describe a rom that syntesizes in Xilinx ISE and Altera Quartus without adding anything by hand (or code). Or is there a way to add some lines into the code but not generate the whole VHDL or Verilog code, e.g. __vhdl__.addLine(\ """attribute romstyle : string; attribute romstyle of q : signal is "M9K";""" ? If not this would be a great improment I think. Kind regards Frederik |
From: Christopher F. <chr...@gm...> - 2012-03-27 16:09:14
|
> attribute romstyle : string; > attribute romstyle of q : signal is "M9K"; > > My questions are if there is a way to describe a rom that syntesizes in > Xilinx ISE and Altera Quartus without adding anything by hand (or code). > <snip. There are also synthesis switches for "auto ROM" extraction. You might want to check if these are set or not. Regards, Chris |
From: Frederik T. <sp...@ne...> - 2012-03-27 16:15:06
|
Hallo Chris, thanks for your answer. I just checked it but "Auto ROM Replacement" was already "On". Another idea? Regards, Frederik Am 27.03.2012 18:09, schrieb Christopher Felton: > >> attribute romstyle : string; >> attribute romstyle of q : signal is "M9K"; >> >> My questions are if there is a way to describe a rom that syntesizes in >> Xilinx ISE and Altera Quartus without adding anything by hand (or code). >> > <snip. > There are also synthesis switches for "auto ROM" extraction. You might > want to check if these are set or not. > > Regards, > Chris > > > ------------------------------------------------------------------------------ > This SF email is sponsosred by: > Try Windows Azure free for 90 days Click Here > http://p.sf.net/sfu/sfd2d-msazure > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list |
From: Frederik T. <sp...@ne...> - 2012-03-27 16:18:31
|
This is the template I found in Quartus II to describe a single port rom: -- Quartus II VHDL Template -- Single-Port ROM library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity single_port_rom is generic ( DATA_WIDTH : natural := 8; ADDR_WIDTH : natural := 8 ); port ( clk : in std_logic; addr : in natural range 0 to 2**ADDR_WIDTH - 1; q : out std_logic_vector((DATA_WIDTH -1) downto 0) ); end entity; architecture rtl of single_port_rom is -- Build a 2-D array type for the RoM subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0); type memory_t is array(2**ADDR_WIDTH-1 downto 0) of word_t; function init_rom return memory_t is variable tmp : memory_t := (others => (others => '0')); begin for addr_pos in 0 to 2**ADDR_WIDTH - 1 loop -- Initialize each address with the address itself tmp(addr_pos) := std_logic_vector(to_unsigned(addr_pos, DATA_WIDTH)); end loop; return tmp; end init_rom; -- Declare the ROM signal and specify a default value. Quartus II -- will create a memory initialization file (.mif) based on the -- default value. signal rom : memory_t := init_rom; begin process(clk) begin if(rising_edge(clk)) then q <= rom(addr); end if; end process; end rtl; It looks different then the case-when statements. Maybe I should generate VHDL code based on this template. Regards, Frederik |
From: Christopher F. <chr...@gm...> - 2012-03-27 18:32:53
|
On 3/27/2012 11:18 AM, Frederik T. wrote: > This is the template I found in Quartus II to describe a single port rom: <snip> > begin > > process(clk) > begin > if(rising_edge(clk)) then > q<= rom(addr); > end if; > end process; > > end rtl; > > It looks different then the case-when statements. > Maybe I should generate VHDL code based on this template. > > > Regards, > > Frederik > I haven't tested/tried. You should be able to use the "clocked" generator in your MyHDL code for the read port and get similar generated VHDL that Quartus should recognize as a ROM. Instead of the always_comb in the read port use a always(clk.posedge). Hope that helps, Chris |
From: Frederik T. <sp...@ne...> - 2012-03-28 08:56:22
|
Hello Chris, I just tried it without success. Without the extra attributes the rom was made off logic elements. After I added them to the VHDL code everything was okay. Do you have another idea? Regards, Frederik Am 27.03.2012 20:32, schrieb Christopher Felton: > On 3/27/2012 11:18 AM, Frederik T. wrote: >> This is the template I found in Quartus II to describe a single port rom: > <snip> >> begin >> >> process(clk) >> begin >> if(rising_edge(clk)) then >> q<= rom(addr); >> end if; >> end process; >> >> end rtl; >> >> It looks different then the case-when statements. >> Maybe I should generate VHDL code based on this template. >> >> >> Regards, >> >> Frederik >> > > I haven't tested/tried. You should be able to use the "clocked" > generator in your MyHDL code for the read port and get similar generated > VHDL that Quartus should recognize as a ROM. Instead of the always_comb > in the read port use a always(clk.posedge). > > Hope that helps, > Chris > > > ------------------------------------------------------------------------------ > This SF email is sponsosred by: > Try Windows Azure free for 90 days Click Here > http://p.sf.net/sfu/sfd2d-msazure > _______________________________________________ > myhdl-list mailing list > myh...@li... > https://lists.sourceforge.net/lists/listinfo/myhdl-list |
From: Frederik T. <sp...@ne...> - 2012-03-28 09:37:13
|
Hi Chris, it works now. I accidently put a reset_n into my ports which is not needed at all - this is clear. That was a problem when I tried the clocked variant. A classical copy paste error. Thanks for your help. I found http://www.altera.com/literature/hb/qts/qts_qii51007.pdf Example 11–3 is exactly what I needed to know. I can conclude that describing a rom needs a clock input to be synthesizable in quartus. My code is now: def twiddlerom(clk, addr, doutr, douti, N, bitwidth): ''' A rom that holds twiddle factors for a FFT addr -- address doutr, douti -- data out, real and imaginary N -- Number of twiddles ''' LMAX = 2**(bitwidth-1) MMAX = 2**(2*bitwidth) def getTwiddles(N): # ... return tuple(ret) tmpcontent = getTwiddles(N) ram = tmpcontent tmp = Signal(intbv(0, min=-MMAX, max=MMAX)[2*bitwidth:]) #@always_comb # doesn't work in quartus #def read(): # tmp.next = ram[int(addr)] @always(clk.posedge) def read(): tmp.next = ram[int(addr)] @always_comb def devide(): doutr.next = tmp[2*bitwidth:bitwidth].signed() douti.next = tmp[bitwidth:0].signed() return read, devide Kind regards from Germany, Frederik |
From: Norbo <Nor...@gm...> - 2012-03-28 10:41:54
|
Just to share my insights on this topic: I actually have never seen a altera FPGA with have dedicated ROM Blocks inside. Altera FPGAs are usually built out of LUT4 Blocks, some Registers, and some dedicated memory or RAM Blocks (they need a positive clockege to output data). So am not quite sure what this (attribute romstyle : string; attribute romstyle of q : signal is "M9K";) does? So my understanding on how quartus normaly maps is: * Rom with asynchron output --> This is put on the FPGA into LUT4 Blocks (this shows up as normal logic (combinatorical functions) synthesis report) * Rom with sycnhron output (output is valid after the positive clk edge) --> This is put on the FPGA into the dedicated memory or RAM Blocks (where the write logic is not used and they are pre initialized by the rom content) * RAM with asynchron output --> This is put on the FPGA into LUT4 Blocks and registers (because the memory blocks need the clkedge for the output) * RAM with synchron output --> This is put on the FPGA into the dedicated memory or RAM Blocks And my understanding on how to write this down in myhdl so that quartus/ inferece the appropriate logic: * Rom with asynchron output: (example from the manual) ---------------------------------------- from myhdl import * def rom(dout, addr, CONTENT): @always_comb def read(): dout.next = CONTENT[int(addr)] return read ---------------------------------------- * Rom with sycnhron output: (output is valid after the positive clk edge) ---------------------------------------- from myhdl import * def rom(clk,dout, addr, CONTENT): @always(clk.posedge) def read(): dout.next = CONTENT[int(addr)] return read ---------------------------------------- * RAM with asynchron output_ (without initialisation of the memory) (example from the manual) ---------------------------------------- from myhdl import * def RAM(dout, din, addr, we, clk, depth=128): """ Ram model """ mem = [Signal(intbv(0)[8:]) for i in range(depth)] @always(clk.posedge) def write(): if we: mem[addr].next = din @always_comb def read(): dout.next = mem[addr] return write, read ---------------------------------------- * RAM with synchron output (without initialisation of the memory): ---------------------------------------- from myhdl import * def RAM(dout, din, addr, we, clk, depth=128): """ Ram model """ mem = [Signal(intbv(0)[8:]) for i in range(depth)] @always(clk.posedge) def write_read(): if we: mem[addr].next = din dout.next = mem[addr] return write_read ---------------------------------------- * RAM with asynchron output (with pre-initialisation of the memory content): Dont know a way to describe this in myhdl (i think the list of signal would need to be initializable) then it could work. * RAM with synchron output (with pre-initialisation of the memory content): Dont know a way to describe this in myhdl greetings norbo Am 28.03.2012, 10:56 Uhr, schrieb Frederik T. <sp...@ne...>: > Hello Chris, > > I just tried it without success. Without the extra attributes the rom > was made off logic elements. After I added them to the VHDL code > everything was okay. > > Do you have another idea? > > > Regards, > > Frederik > > Am 27.03.2012 20:32, schrieb Christopher Felton: >> On 3/27/2012 11:18 AM, Frederik T. wrote: >>> This is the template I found in Quartus II to describe a single port >>> rom: >> <snip> >>> begin >>> >>> process(clk) >>> begin >>> if(rising_edge(clk)) then >>> q<= rom(addr); >>> end if; >>> end process; >>> >>> end rtl; >>> >>> It looks different then the case-when statements. >>> Maybe I should generate VHDL code based on this template. >>> >>> >>> Regards, >>> >>> Frederik >>> >> >> I haven't tested/tried. You should be able to use the "clocked" >> generator in your MyHDL code for the read port and get similar generated >> VHDL that Quartus should recognize as a ROM. Instead of the always_comb >> in the read port use a always(clk.posedge). >> >> Hope that helps, >> Chris >> >> >> ------------------------------------------------------------------------------ >> This SF email is sponsosred by: >> Try Windows Azure free for 90 days Click Here >> http://p.sf.net/sfu/sfd2d-msazure >> _______________________________________________ >> myhdl-list mailing list >> myh...@li... >> https://lists.sourceforge.net/lists/listinfo/myhdl-list > > ------------------------------------------------------------------------------ > This SF email is sponsosred by: > Try Windows Azure free for 90 days Click Here > http://p.sf.net/sfu/sfd2d-msazure -- Erstellt mit Operas revolutionärem E-Mail-Modul: http://www.opera.com/mail/ |
From: Frederik T. <sp...@ne...> - 2012-03-30 07:29:52
|
Hello Norbo, thank you for your email. > So am not quite sure what this (attribute romstyle : string; attribute > romstyle of q : signal is "M9K";) does? I think this tells Quartus to build a rom with M9K memory blocks. The device must support the TriMatrix Memory architecture. http://quartushelp.altera.com/11.1/mergedProjects/hdl/vhdl/vhdl_file_dir_romstyle.htm.htm The synchronous rom doesn't need this extra attribute because Quartus automatically builds a rom with memory blocks if "Auto ROM Replacement" is activated. This is the default setting. http://quartushelp.altera.com/11.1/mergedProjects/logicops/logicops/def_auto_rom_recognition.htm Kind regards from Germany, Frederik |