- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think such code is optimised off to no registers so address is given 4 only
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
IS it an internal FPGA ram, or external ram?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It's an internal M9K ram.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't understand your sentence.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- What is this hold time? --- Quote End --- It's the "hold" variable in the conditional test.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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...- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 !
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page