Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16624 Discussions

RAM 1-port mega function - Single Port Ram module

Altera_Forum
Honored Contributor II
2,591 Views

hello,  

 

I created a memory ram 1k x 8bit through the MegaWizard by Quartus II. 

The process generated the following code that works very well: 

 

-- ============================================================ -- megafunction wizard: %RAM: 1-PORT% -- GENERATION: STANDARD -- VERSION: WM1.0 -- MODULE: altsyncram -- File Name: RAM.vhd -- Megafunction Name(s): altsyncram -- -- Simulation Library Files(s): altera_mf -- ============================================================ LIBRARY ieee; USE ieee.std_logic_1164.all; LIBRARY altera_mf; USE altera_mf.all; ENTITY RAM IS PORT( address : IN STD_LOGIC_VECTOR (9 DOWNTO 0); clock : IN STD_LOGIC := '1'; data : IN STD_LOGIC_VECTOR (7 DOWNTO 0); wren : IN STD_LOGIC ; q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) ); END RAM; ARCHITECTURE SYN OF ram IS SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0); COMPONENT altsyncram GENERIC( clock_enable_input_a : STRING; clock_enable_output_a : STRING; intended_device_family : STRING; lpm_hint : STRING; lpm_type : STRING; numwords_a : NATURAL; operation_mode : STRING; outdata_aclr_a : STRING; outdata_reg_a : STRING; power_up_uninitialized : STRING; read_during_write_mode_port_a : STRING; widthad_a : NATURAL; width_a : NATURAL; width_byteena_a : NATURAL ); PORT( address_a : IN STD_LOGIC_VECTOR (9 DOWNTO 0); clock0 : IN STD_LOGIC ; data_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0); wren_a : IN STD_LOGIC ; q_a : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) ); END COMPONENT; BEGIN q <= sub_wire0(7 DOWNTO 0); altsyncram_component : altsyncram GENERIC MAP( clock_enable_input_a => "BYPASS", clock_enable_output_a => "BYPASS", intended_device_family => "Cyclone IV GX", lpm_hint => "ENABLE_RUNTIME_MOD=NO", lpm_type => "altsyncram", numwords_a => 1024, operation_mode => "SINGLE_PORT", outdata_aclr_a => "NONE", outdata_reg_a => "CLOCK0", power_up_uninitialized => "FALSE", read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ", widthad_a => 10, width_a => 8, width_byteena_a => 1 ) PORT MAP( address_a => address, clock0 => clock, data_a => data, wren_a => wren, q_a => sub_wire0 ); END SYN; -- ============================================================ -- CNX file retrieval info -- ============================================================ -- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0" -- Retrieval info: PRIVATE: AclrAddr NUMERIC "0" -- Retrieval info: PRIVATE: AclrByte NUMERIC "0" -- Retrieval info: PRIVATE: AclrData NUMERIC "0" -- Retrieval info: PRIVATE: AclrOutput NUMERIC "0" -- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0" -- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8" -- Retrieval info: PRIVATE: BlankMemory NUMERIC "1" -- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0" -- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0" -- Retrieval info: PRIVATE: Clken NUMERIC "0" -- Retrieval info: PRIVATE: DataBusSeparated NUMERIC "1" -- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0" -- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A" -- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0" -- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV GX" -- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0" -- Retrieval info: PRIVATE: JTAG_ID STRING "NONE" -- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0" -- Retrieval info: PRIVATE: MIFfilename STRING "" -- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "1024" -- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0" -- Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3" -- Retrieval info: PRIVATE: RegAddr NUMERIC "1" -- Retrieval info: PRIVATE: RegData NUMERIC "1" -- Retrieval info: PRIVATE: RegOutput NUMERIC "1" -- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0" -- Retrieval info: PRIVATE: SingleClock NUMERIC "1" -- Retrieval info: PRIVATE: UseDQRAM NUMERIC "1" -- Retrieval info: PRIVATE: WRCONTROL_ACLR_A NUMERIC "0" -- Retrieval info: PRIVATE: WidthAddr NUMERIC "10" -- Retrieval info: PRIVATE: WidthData NUMERIC "8" -- Retrieval info: PRIVATE: rden NUMERIC "0" -- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all -- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS" -- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS" -- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV GX" -- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO" -- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram" -- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "1024" -- Retrieval info: CONSTANT: OPERATION_MODE STRING "SINGLE_PORT" -- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE" -- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0" -- Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE" -- Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_A STRING "NEW_DATA_NO_NBE_READ" -- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "10" -- Retrieval info: CONSTANT: WIDTH_A NUMERIC "8" -- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1" -- Retrieval info: USED_PORT: address 0 0 10 0 INPUT NODEFVAL "address" -- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock" -- Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL "data" -- Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q" -- Retrieval info: USED_PORT: wren 0 0 0 0 INPUT NODEFVAL "wren" -- Retrieval info: CONNECT: @address_a 0 0 10 0 address 0 0 10 0 -- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0 -- Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0 -- Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0 -- Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0 -- Retrieval info: GEN_FILE: TYPE_NORMAL RAM.vhd TRUE -- Retrieval info: GEN_FILE: TYPE_NORMAL RAM.inc FALSE -- Retrieval info: GEN_FILE: TYPE_NORMAL RAM.cmp FALSE -- Retrieval info: GEN_FILE: TYPE_NORMAL RAM.bsf FALSE -- Retrieval info: GEN_FILE: TYPE_NORMAL RAM_inst.vhd FALSE -- Retrieval info: LIB_FILE: altera_mf  

 

However, some features do not meet my needs. 

 

First problem: The Altera design, has two data bus, one to input (write) data and another to output data (read). 

 

Second problem: The Altera desing, has only one control input (write data enable). 

 

Third problem: All buses, are STD_LOGIC_VECTOR. 

 

I need a device, that has a bi-directional data bus, type std_logic (not vector). 

I need a device, that has a address bus, type std_logic (not vector). 

I need a device, that has one read/write pin control (RW) and one chip select to  

to put the bi-directional data bus in tri-state (CS). 

 

Something like the following port: 

ENTITY RAM IS PORT( A0 : IN STD_LOGIC; A1 : IN STD_LOGIC; A2 : IN STD_LOGIC; A3 : IN STD_LOGIC; A4 : IN STD_LOGIC; A5 : IN STD_LOGIC; A6 : IN STD_LOGIC; A7 : IN STD_LOGIC; A8 : IN STD_LOGIC; A9 : IN STD_LOGIC; D7 : INOUT STD_LOGIC; D6 : INOUT STD_LOGIC; D5 : INOUT STD_LOGIC; D4 : INOUT STD_LOGIC; D3 : INOUT STD_LOGIC; D2 : INOUT STD_LOGIC; D1 : INOUT STD_LOGIC; D0 : INOUT STD_LOGIC; CLK : IN STD_LOGIC := '1'; CS : IN STD_LOGIC; RW : IN STD_LOGIC ); END RAM;  

I got get close this result... 

I got change buses and created de CS pin control... 

But, I have serius problems with the bi-directional data bus... 

I could not create a correct logic to manage the bi-direcinal bus in the three possibilities:  

READING, WRITING and DISABLED. 

 

I'm still learning VHDL and I need some help from you guys!!!  

 

Thank you very much. 

:)
0 Kudos
3 Replies
Altera_Forum
Honored Contributor II
1,385 Views

Why do you want bi-directional? FPGAs only have bi-directional interfaces on the pins. There are no internal bi-directional abilities, and if you try and code that way they just get separated into read and write muxes. 

Secondly, why not just pull all the individual ports out to connect to each bit? you can acccess each data element by connecting data(0), data(1) etc. But most people are just happy to connect the bus. 

 

The altera core cannot do what you want. I suggest writing a wrapper around the ram if you really really want to interface it the way you described, otherwise you will have to use the ram the way it was intended (that also maps nicely to the hardware rams.)
0 Kudos
Altera_Forum
Honored Contributor II
1,385 Views

After eating enough rice and beans and read with enough attention the following documents: 

 

http://quartushelp.altera.com/13.0/mergedprojects/hdl/mega/mega_file_altsynch_ram.htm 

RAM Megafunction User Guide v2.0 2007.pdf 

 

I got a solution to my problem posted here. 

 

I'm building a TRS80 using the Quartus II design the graphic (block file / schematic diagram). 

And I'm keeping the old fashioned diagramming, not using closed buses and closed blocks. 

 

I'm posting below how was the result of the code to the RAM memory, 

in my case, will be a 2114 (1k x 8) and the image of its symbol. 

 

I hope this helps someone with the same difficulties as I had. 

-- ============================================================ -- megafunction wizard: %RAM: 1-PORT% -- GENERATION: STANDARD -- VERSION: WM1.0 -- MODULE: altsyncram -- File Name: RAM.vhd -- Megafunction Name(s): altsyncram -- Simulation Library Files(s): altera_mf -- ============================================================ LIBRARY ieee; USE ieee.std_logic_1164.all; LIBRARY altera_mf; USE altera_mf.all; ENTITY RAM IS PORT( A0 : IN STD_LOGIC; A1 : IN STD_LOGIC; A2 : IN STD_LOGIC; A3 : IN STD_LOGIC; A4 : IN STD_LOGIC; A5 : IN STD_LOGIC; A6 : IN STD_LOGIC; A7 : IN STD_LOGIC; A8 : IN STD_LOGIC; A9 : IN STD_LOGIC; D7 : INOUT STD_LOGIC := 'Z'; D6 : INOUT STD_LOGIC := 'Z'; D5 : INOUT STD_LOGIC := 'Z'; D4 : INOUT STD_LOGIC := 'Z'; D3 : INOUT STD_LOGIC := 'Z'; D2 : INOUT STD_LOGIC := 'Z'; D1 : INOUT STD_LOGIC := 'Z'; D0 : INOUT STD_LOGIC := 'Z'; CLK : IN STD_LOGIC := '1'; CS : IN STD_LOGIC := '1'; RW : IN STD_LOGIC := '1' -- address : IN STD_LOGIC_VECTOR (9 DOWNTO 0); -- clock : IN STD_LOGIC := '1'; -- data : IN STD_LOGIC_VECTOR (7 DOWNTO 0); -- rden : IN STD_LOGIC := '1'; -- wren : IN STD_LOGIC ; -- q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) ); END RAM; ARCHITECTURE SYN OF ram IS SIGNAL sub_wire0 : STD_LOGIC_VECTOR (7 DOWNTO 0); SIGNAL sub_wire1 : STD_LOGIC_VECTOR (7 DOWNTO 0); COMPONENT altsyncram GENERIC( clock_enable_input_a : STRING; clock_enable_output_a : STRING; intended_device_family : STRING; lpm_hint : STRING; lpm_type : STRING; numwords_a : NATURAL; operation_mode : STRING; outdata_aclr_a : STRING; outdata_reg_a : STRING; power_up_uninitialized : STRING; read_during_write_mode_port_a : STRING; widthad_a : NATURAL; width_a : NATURAL; width_byteena_a : NATURAL ); PORT( address_a : IN STD_LOGIC_VECTOR (9 DOWNTO 0); clock0 : IN STD_LOGIC ; data_a : IN STD_LOGIC_VECTOR (7 DOWNTO 0); wren_a : IN STD_LOGIC ; q_a : OUT STD_LOGIC_VECTOR (7 DOWNTO 0); rden_a : IN STD_LOGIC ); END COMPONENT; BEGIN -- q <= sub_wire0(7 DOWNTO 0); (D7,D6,D5,D4,D3,D2,D1,D0) <= sub_wire0(7 DOWNTO 0) when ((CS = '0') AND (RW = '1')) else std_logic_vector'("ZZZZZZZZ"); sub_wire1(7 DOWNTO 0) <= (D7,D6,D5,D4,D3,D2,D1,D0) when ((CS = '0') AND (RW = '0')) else NULL; altsyncram_component : altsyncram GENERIC MAP( clock_enable_input_a => "BYPASS", clock_enable_output_a => "BYPASS", intended_device_family => "Cyclone IV E", lpm_hint => "ENABLE_RUNTIME_MOD=NO", lpm_type => "altsyncram", numwords_a => 1024, operation_mode => "SINGLE_PORT", outdata_aclr_a => "NONE", outdata_reg_a => "CLOCK0", power_up_uninitialized => "FALSE", read_during_write_mode_port_a => "NEW_DATA_NO_NBE_READ", widthad_a => 10, width_a => 8, width_byteena_a => 1 ) PORT MAP( -- address_a => address, address_a => A9&A8&A7&A6&A5&A4&A3&A2&A1&A0, -- clock0 => clock, clock0 => CLK, -- data_a => data, data_a => sub_wire1, -- wren_a => wren, wren_a => (NOT RW) AND (NOT CS), -- rden_a => rden, rden_a => RW AND (NOT CS), q_a => sub_wire0 ); END SYN;  

rmk: would also like to post a comment to something that I could not understand, 

for not yet understand VHDL very well... (I left the original code annotated). 

 

In the part that is in bold, I tried to use the following lines: 

D7&D6&D5&D4&D3&D2&D1&D0 <= sub_wire0(7 DOWNTO 0) when ((CS = '0') AND (RW = '1')) else std_logic_vector'("ZZZZZZZZ"); sub_wire1(7 DOWNTO 0) <= D7&D6&D5&D4&D3&D2&D1&D0 when ((CS = '0') AND (RW = '0')) else NULL;  

The second line works, but the first line not work. :( 

 

Also, follows a memory image of the memory symbol.
0 Kudos
Altera_Forum
Honored Contributor II
1,385 Views

The first line doesnt work because you cannot perform a concatenation on the LHS of an assignment, the origional code shows an aggregation. 

The second line does work but it creates a latch - which is not a nice thing to have in an FPGA.
0 Kudos
Reply