- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi every body!
I'm a newbie in SOPC system design. I'm trying to create a custom ip, which has an internal RAM (declare as an array) and contacts with NIOS via Avalon MM bus. I'm using DE2 and this is my code for that ip:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
entity PIXELS_BUFFER is
port(
--- NIOS
clock: IN STD_LOGIC;
reset: IN STD_LOGIC;
address: IN STD_LOGIC_VECTOR(3 downto 0); -- for testing
chipselect: IN STD_LOGIC;
byteenable: IN STD_LOGIC;
writedata: IN STD_LOGIC_VECTOR(7 downto 0); -- 8-bit data
readdata: OUT STD_LOGIC_VECTOR(7 downto 0); -- 8-bit data
write: IN STD_LOGIC;
read: IN STD_LOGIC
);
end PIXELS_BUFFER;
architecture Behavioral of PIXELS_BUFFER is
type ram_type is array (0 to 15) of std_logic_vector(7 downto 0);
--- ROM definition
signal RAM_CONTENT: ram_type := (
"00000000",
"00000001",
"00000010",
"00000011",
"00000100",
"00000101",
"00000110",
"00000111",
"00001000",
"00001001",
"00001010",
"00001011",
"00001100",
"00001101",
"00001110",
"00001111"
);
begin
process(clock, reset, address, chipselect, byteenable, read, write, writedata)
begin
if(rising_edge(clock)) then
if(chipselect='1') then
if(read='1') then
readdata <= RAM_CONTENT(conv_integer(address));
end if;
if(write='1') then
RAM_CONTENT(conv_integer(address)) <= writedata;
end if;
end if;
end if;
end process;
end Behavioral;
In SOPC, I added my IP as:
signal | Interface | Signal type | WIDTH|Direction
clock | clock | clk | 1 | IN
reset | reset | reset | 1 | IN
address | avalon_slave_0 | address | 4 | IN
chipselect | avalon_slave_0 | chipselect | 1 | IN
byteenable | avalon_slave_0 | byteenable | 1 | IN
writedata | avalon_slave_0 | writedata | 7 | IN
readdata | avalon_slave_0 | readdata | 7 | OUT
write | avalon_slave_0 | write | 1 | IN
read | avalon_slave_0 | read | 1 | IN
my first work is reading RAM_CONTENT but i saw wrong result in my NIOS :((
# include <stdio.h>
# include <io.h> // using IORD_8DIRECT
# include "system.h" // using PIXELS_BUFFER_0_BASE
int main()
{
int i;
printf("Hello from Nios II!\n");
for(i=0; i<16; i++)
// read byte by byte
printf("Addr: %i\t%i \n", i, IORD_8DIRECT(PIXELS_BUFFER_0_BASE, i));
return 0;
}
Results:
Addr: 0 0
Addr: 1 0
Addr: 2 1
Addr: 3 2
Addr: 4 3
Addr: 5 4
Addr: 6 5
Addr: 7 6
Addr: 8 7
Addr: 9 8
Addr: 10 9
Addr: 11 10
Addr: 12 11
Addr: 13 12
Addr: 14 13
Addr: 15 14
Why did it show that? I had no delay when transfering data to avalon bus, or no wait cycle in SOPC IP. Attach file is my project. Could anybody help me? Thanks^^
Link Copied
6 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
i believe your error is that there should be a read wait state. just as an fyi, there is no reason to use the read signal, you could have just always assigned readdata to the ram[address].
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi again,
I just modified code vhdl ( add 1 when calculating address to read ram_content)
if(read='1') then
--- readdata <= RAM_CONTENT(conv_integer(address));
readdata <= RAM_CONTENT(conv_integer(address)+1); -- add 1
end if;
then i ran this code in NIOS:
# include <stdio.h>
# include <io.h>
# include "system.h"
int main()
{
int i;
printf("Hello from Nios II!\n");
printf("refill content of RAM\n");
for(i=0; i<16; i++)
IOWR_8DIRECT(PIXELS_BUFFER_0_BASE, i, i);
printf("check wrote content\n");
for(i=0; i<16; i++)
{
char x = IORD_8DIRECT(PIXELS_BUFFER_0_BASE, i);
printf("Addr: %i\t%i\t", i, x);
if(x!=i) printf(" <= ERROR\n");
else printf("\n");
}
printf(" check again\n");
for(i=0; i<16; i++)
{
char x = IORD_8DIRECT(PIXELS_BUFFER_0_BASE, i);
printf("Addr: %i\t%i\t", i, x);
if(x!=i) printf(" <= ERROR\n");
else printf("\n");
}
printf("refill content but with new data\n");
for(i=0; i<16; i++)
IOWR_8DIRECT(PIXELS_BUFFER_0_BASE, i, 15-i); // add 0: 15 , add 1:14 ...
printf("check wrote content\n");
for(i=0; i<16; i++)
{
char x = IORD_8DIRECT(PIXELS_BUFFER_0_BASE, i);
printf("Addr: %i\t%i\t", i, x);
if(x!=15-i) printf(" <= ERROR\n");
else printf("\n");
}
printf("check again\n");
for(i=0; i<16; i++)
{
char x = IORD_8DIRECT(PIXELS_BUFFER_0_BASE, i);
printf("Addr: %i\t%i\t", i, x);
if(x!=15-i) printf(" <= ERROR\n");
else printf("\n");
}
return 0;
}
I received new result, something still wrong, but in special case, as u see below:
Hello from Nios II!
refill content of RAM
check wrote content
Addr: 0 15 <= ERROR
Addr: 1 1
Addr: 2 2
Addr: 3 3
Addr: 4 4
Addr: 5 5
Addr: 6 6
Addr: 7 7
Addr: 8 8
Addr: 9 9
Addr: 10 10
Addr: 11 11
Addr: 12 12
Addr: 13 13
Addr: 14 14
Addr: 15 15
check again
Addr: 0 0
Addr: 1 1
Addr: 2 2
Addr: 3 3
Addr: 4 4
Addr: 5 5
Addr: 6 6
Addr: 7 7
Addr: 8 8
Addr: 9 9
Addr: 10 10
Addr: 11 11
Addr: 12 12
Addr: 13 13
Addr: 14 14
Addr: 15 15
refill content but with new data
check wrote content
Addr: 0 0 <= ERROR
Addr: 1 14
Addr: 2 13
Addr: 3 12
Addr: 4 11
Addr: 5 10
Addr: 6 9
Addr: 7 8
Addr: 8 7
Addr: 9 6
Addr: 10 5
Addr: 11 4
Addr: 12 3
Addr: 13 2
Addr: 14 1
Addr: 15 0
check again
Addr: 0 15
Addr: 1 14
Addr: 2 13
Addr: 3 12
Addr: 4 11
Addr: 5 10
Addr: 6 9
Addr: 7 8
Addr: 8 7
Addr: 9 6
Addr: 10 5
Addr: 11 4
Addr: 12 3
Addr: 13 2
Addr: 14 1
Addr: 15 0
I still dont known what happened. When i rewrite data at offset 0, then first read bring me wrong number, but in the 2nd, it became right number. hix, could anybody explain that for me? Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- i believe your error is that there should be a read wait state. just as an fyi, there is no reason to use the read signal, you could have just always assigned readdata to the ram[address]. --- Quote End --- thank dwesterg, did u mean i would bypass the read signal, just simple assign data like:
begin
readdata <= RAM_CONTENT(conv_integer(address));
process(...) -- for writing data
...
end process;
end behav;
i will do a try :) and report in this thread, thanks again :x
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- thank dwesterg, did u mean i would bypass the read signal, just simple assign data like:
begin
readdata <= RAM_CONTENT(conv_integer(address));
process(...) -- for writing data
...
end process;
end behav;
i will do a try :) and report in this thread, thanks again :x --- Quote End --- THANK dwesterg SO MUCH!!! It returned right number. Why did i think like you :| I think address will be avaible before read signal is pulled up, as waveform in sopc. Oh, sometime, A small mistake is too hard to recognize. Thank dwesterg many, many times :x
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
the availability of signals is dependant on the setup and wait settings in your hw.tcl file. having address available early is entirely plausible if you specify the behaviour in your hw.tcl file.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would recommend making your slave have 32 data bits - even if the top 24 are ignored on writes and return 0 on reads.
An 8 bit slave will always see 4 bus cycles when the NIOS doe a byte access to it. On writes three of theses will have the byte enable de-asserted. However the NIOS always asserts all 4 byte enables on reads - so you'll see 4 separate read cycles for each cpu byte read.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page