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

VHDL writing in memory

Altera_Forum
Honored Contributor II
3,534 Views

Hi, 

I have a hardware design running on a Cyclone IV FPGA and a software part running on a Nios II cpu on the very same FPGA. Both are sharing a dual port FPGA memory. I want the hardware part to write data on the memory and the software part to read it. The reading seems to be OK but the writing is not. Here is the VHDL code I use: 

library ieee;use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.numeric_std.all; entity ctrl is port( data : out std_logic_vector(7 downto 0); wen : out std_logic := '0'; addr : out std_logic_vector(14 downto 0):=(others=>'0'); clk : in std_logic); end ctrl; architecture rtl of ctrl is signal step : integer := 1; begin process(clk) begin if clk'event and clk='1' then data <= "00000001"; if step<4 then step <= step+1; end if; addr <= std_logic_vector(to_unsigned(step, addr'length)); wen <= '1'; end if; end process; end rtl;  

What I'd expect is the values written at addresses 2, 3 and 4 to be 1 but I only read 1 at address 4, others are 0. 

I'm sure I'm messing something up in the sequential and concurrent statements but I can't solve this. 

Could someone help me? 

Thanks.
0 Kudos
17 Replies
Altera_Forum
Honored Contributor II
1,889 Views

it looks fine to me, code will generate addresses 1 to 4 and write 1 on sequential clocks. But this is a simple controller. Do you need to hold write enable for any length of time other than 1 clock (because when it reaches 4, it will write the value 0x00000001 to the memory forever? Where is the code for the memory? 

 

As a side note: you shouldnt be using the std_logic_arith library. Apart from being a non-standard library, it has conflicts with numeric_std. numeric_std is the IEEE standard library.
0 Kudos
Altera_Forum
Honored Contributor II
1,889 Views

I think such code is optimised off to no registers so address is given 4 only

0 Kudos
Altera_Forum
Honored Contributor II
1,889 Views

I knew that for the libraries, I surely have forgotten this when writing. It's corrected. 

 

I don't find the memory signals documentation so the hold time may not be correct. 

Do you know where I can find this documentation?
0 Kudos
Altera_Forum
Honored Contributor II
1,889 Views

IS it an internal FPGA ram, or external ram?

0 Kudos
Altera_Forum
Honored Contributor II
1,889 Views

It's an internal M9K ram.

0 Kudos
Altera_Forum
Honored Contributor II
1,889 Views

Here's my new code to have a large hold time: 

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity ctrl is port( data : out std_logic_vector(7 downto 0); wen : out std_logic := '0'; addr : out std_logic_vector(14 downto 0):=(others=>'0'); clk : in std_logic); end ctrl; architecture rtl of ctrl is signal step : integer := 1; signal hold : integer := 0; begin process(clk) begin if clk'event and clk='1' then if step<5 then if hold=10 then step <= step+1; hold <= 0; end if; hold <= hold+1; wen <= '1'; else wen <= '0'; end if; data <= "00000001"; addr <= std_logic_vector(to_unsigned(step, addr'length)); end if; end process; end rtl;  

Now addresses 1 and 2 are equal to 1 when others are 0. I don't understand what's happening.
0 Kudos
Altera_Forum
Honored Contributor II
1,889 Views

 

--- Quote Start ---  

Here's my new code to have a large hold time: 

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity ctrl is port( data : out std_logic_vector(7 downto 0); wen : out std_logic := '0'; addr : out std_logic_vector(14 downto 0):=(others=>'0'); clk : in std_logic); end ctrl; architecture rtl of ctrl is signal step : integer := 1; signal hold : integer := 0; begin process(clk) begin if clk'event and clk='1' then if step<5 then if hold=10 then step <= step+1; hold <= 0; end if; hold <= hold+1; wen <= '1'; else wen <= '0'; end if; data <= "00000001"; addr <= std_logic_vector(to_unsigned(step, addr'length)); end if; end process; end rtl;  

Now addresses 1 and 2 are equal to 1 when others are 0. I don't understand what's happening. 

--- Quote End ---  

 

 

insert hold <= hold + 1; 

before the if condition of reset it to zero
0 Kudos
Altera_Forum
Honored Contributor II
1,889 Views

I don't understand your sentence.

0 Kudos
Altera_Forum
Honored Contributor II
1,889 Views

 

--- Quote Start ---  

I don't understand your sentence. 

--- Quote End ---  

 

 

process(clk) begin if clk'event and clk='1' then if step<5 then hold <= hold+1; if hold=10 then step <= step+1; hold <= 0; end if; wen <= '1'; else wen <= '0'; end if; data <= "00000001"; addr <= std_logic_vector(to_unsigned(step, addr'length)); end if; end process;
0 Kudos
Altera_Forum
Honored Contributor II
1,889 Views

That works but I don't understand what is really different. Can you explain? 

 

Also I have to make the hold time to be at least 8 clock cycles. Is there a document telling that? 

 

Thank you anyway.
0 Kudos
Altera_Forum
Honored Contributor II
1,889 Views

The difference is because a signal in VHDL takes the last value assigned to it. In your origional code, it is reset inside the the "if hold = 10 then" branch, but this is overridden with hold <= hold + 1, hence it is never reset to 0.

0 Kudos
Altera_Forum
Honored Contributor II
1,889 Views

 

--- Quote Start ---  

That works but I don't understand what is really different. Can you explain? 

 

--- Quote End ---  

 

 

There are two ways to set logic priority: 

explicit and default 

 

explicit 

if count = 10 then count <= 0; else count <= count + 1; end if;  

 

default (conditional) 

count <= count + 1; if count = 10 then count <= 0; end if;  

 

In vhdl process the last statement overwrites so if this last statement is conditional that is ok. 

if it is not conditional like your code then it implies unconditional update and compiler optimises off the previous assignment 

 

 

--- Quote Start ---  

 

Also I have to make the hold time to be at least 8 clock cycles. Is there a document telling that? 

 

--- Quote End ---  

 

 

What is this hold time?
0 Kudos
Altera_Forum
Honored Contributor II
1,889 Views

 

--- Quote Start ---  

What is this hold time? 

--- Quote End ---  

 

It's the "hold" variable in the conditional test.
0 Kudos
Altera_Forum
Honored Contributor II
1,889 Views

 

--- Quote Start ---  

It's the "hold" variable in the conditional test. 

--- Quote End ---  

 

 

I don't get it. hold is your local variable and you ask for a document on it? 

You are already delaying hold for 10 clock cycles before incrementing step.  

if you want further factor of 8 then just make it 80 instead of 10 so you increment every 80 clocks. 

 

You also need to constrain the range of your integers
0 Kudos
Altera_Forum
Honored Contributor II
1,889 Views

OK for the range. 

 

My hold local variable is there for the signals to keep a value for several clock cycles. Maybe it's not the good way of doing that. Tell me how to do that, I'm not used to it...
0 Kudos
Altera_Forum
Honored Contributor II
1,889 Views

 

--- Quote Start ---  

OK for the range. 

 

My hold local variable is there for the signals to keep a value for several clock cycles. Maybe it's not the good way of doing that. Tell me how to do that, I'm not used to it... 

--- Quote End ---  

 

 

you already done that. Here is my version 

 

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity ctrl is port( data : out std_logic_vector(7 downto 0); wen : out std_logic := '0'; addr : out std_logic_vector(14 downto 0):=(others=>'0'); clk : in std_logic); end ctrl; architecture rtl of ctrl is signal count1 : integer range 0 to 15 := 0; signal count2 : integer range 0 to 7 := 0; begin process(clk) begin if clk'event and clk='1' then wen <= '0'; if count1 /= 15 then count1 <= count1 + 1; else count1 <= 0; if count2 /= 7 then count2 <= count2 + 1; else count2 <= 0; wen <= '1'; end if; end if; end if; end process; data <= std_logic_vector(to_unsigned(count1, data'length)); addr <= std_logic_vector(to_unsigned(count2, addr'length)); end rtl;
0 Kudos
Altera_Forum
Honored Contributor II
1,889 Views

You generate a "wen" (write enable) which is active for one period of clk (20ns ?)  

Is it enough for your RAM ? 

 

With your last code, you are only writing at address addr = 0 !
0 Kudos
Reply