- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hai,
I have vhdl code for store a constant in ROM. The ROM is divided into odd and even; ROMO and ROME as shown below:
library IEEE; use IEEE.STD_LOGIC_1164.all; -- use ieee.STD_LOGIC_signed.all; use IEEE.STD_LOGIC_arith.all; use WORK.MDCT_PKG.all; entity ROMO is port( addr : in STD_LOGIC_VECTOR(ROMADDR_W-1 downto 0); clk : in STD_LOGIC; datao : out STD_LOGIC_VECTOR(ROMDATA_W-1 downto 0) ); end ROMO; architecture RTL of ROMO is type ROM_TYPE is array (0 to 2**ROMADDR_W-1) of STD_LOGIC_VECTOR(ROMDATA_W-1 downto 0); constant rom : ROM_TYPE := ( (others => '0'), conv_std_logic_vector( GP,ROMDATA_W ), conv_std_logic_vector( FP,ROMDATA_W ), conv_std_logic_vector( FP+GP,ROMDATA_W ), conv_std_logic_vector( EP,ROMDATA_W ), conv_std_logic_vector( EP+GP,ROMDATA_W ), conv_std_logic_vector( EP+FP,ROMDATA_W ), conv_std_logic_vector( EP+FP+GP,ROMDATA_W ), conv_std_logic_vector( DP,ROMDATA_W ), conv_std_logic_vector( DP+GP,ROMDATA_W ), conv_std_logic_vector( DP+FP,ROMDATA_W ), conv_std_logic_vector( DP+FP+GP,ROMDATA_W ), conv_std_logic_vector( DP+EP,ROMDATA_W ), conv_std_logic_vector( DP+EP+GP,ROMDATA_W ), conv_std_logic_vector( DP+EP+FP,ROMDATA_W ), conv_std_logic_vector( DP+EP+FP+GP,ROMDATA_W ), (others => '0'), conv_std_logic_vector( FM,ROMDATA_W ), conv_std_logic_vector( DM,ROMDATA_W ), conv_std_logic_vector( DM+FM,ROMDATA_W ), conv_std_logic_vector( GM,ROMDATA_W ), conv_std_logic_vector( GM+FM,ROMDATA_W ), conv_std_logic_vector( GM+DM,ROMDATA_W ), conv_std_logic_vector( GM+DM+FM,ROMDATA_W ), conv_std_logic_vector( EP,ROMDATA_W ), conv_std_logic_vector( EP+FM,ROMDATA_W ), conv_std_logic_vector( EP+DM,ROMDATA_W ), conv_std_logic_vector( EP+DM+FM,ROMDATA_W ), conv_std_logic_vector( EP+GM,ROMDATA_W ), conv_std_logic_vector( EP+GM+FM,ROMDATA_W ), conv_std_logic_vector( EP+GM+DM,ROMDATA_W ), conv_std_logic_vector( EP+GM+DM+FM,ROMDATA_W ), (others => '0'), conv_std_logic_vector( EP,ROMDATA_W ), conv_std_logic_vector( GP,ROMDATA_W ), conv_std_logic_vector( EP+GP,ROMDATA_W ), conv_std_logic_vector( DM,ROMDATA_W ), conv_std_logic_vector( DM+EP,ROMDATA_W ), conv_std_logic_vector( DM+GP,ROMDATA_W ), conv_std_logic_vector( DM+GP+EP,ROMDATA_W ), conv_std_logic_vector( FP,ROMDATA_W ), conv_std_logic_vector( FP+EP,ROMDATA_W ), conv_std_logic_vector( FP+GP,ROMDATA_W ), conv_std_logic_vector( FP+GP+EP,ROMDATA_W ), conv_std_logic_vector( FP+DM,ROMDATA_W ), conv_std_logic_vector( FP+DM+EP,ROMDATA_W ), conv_std_logic_vector( FP+DM+GP,ROMDATA_W ), conv_std_logic_vector( FP+DM+GP+EP,ROMDATA_W ), (others => '0'), conv_std_logic_vector( DM,ROMDATA_W ), conv_std_logic_vector( EP,ROMDATA_W ), conv_std_logic_vector( EP+DM,ROMDATA_W ), conv_std_logic_vector( FM,ROMDATA_W ), conv_std_logic_vector( FM+DM,ROMDATA_W ), conv_std_logic_vector( FM+EP,ROMDATA_W ), conv_std_logic_vector( FM+EP+DM,ROMDATA_W ), conv_std_logic_vector( GP,ROMDATA_W ), conv_std_logic_vector( GP+DM,ROMDATA_W ), conv_std_logic_vector( GP+EP,ROMDATA_W ), conv_std_logic_vector( GP+EP+DM,ROMDATA_W ), conv_std_logic_vector( GP+FM,ROMDATA_W ), conv_std_logic_vector( GP+FM+DM,ROMDATA_W ), conv_std_logic_vector( GP+FM+EP,ROMDATA_W ), conv_std_logic_vector( GP+FM+EP+DM,ROMDATA_W ) ); begin process(clk) begin if clk = '1' and clk'event then datao <= rom( CONV_INTEGER(UNSIGNED(addr)) ); end if; end process; end RTL;
library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.STD_LOGIC_arith.all; use WORK.MDCT_PKG.all; entity ROME is port( addr : in STD_LOGIC_VECTOR(ROMADDR_W-1 downto 0); clk : in STD_LOGIC; datao : out STD_LOGIC_VECTOR(ROMDATA_W-1 downto 0) ); end ROME; architecture RTL of ROME is type ROM_TYPE is array (0 to (2**ROMADDR_W)-1) of STD_LOGIC_VECTOR(ROMDATA_W-1 downto 0); constant rom : ROM_TYPE := ( (others => '0'), conv_std_logic_vector( AP,ROMDATA_W ), conv_std_logic_vector( AP,ROMDATA_W ), conv_std_logic_vector( AP+AP,ROMDATA_W ), conv_std_logic_vector( AP,ROMDATA_W ), conv_std_logic_vector( AP+AP,ROMDATA_W ), conv_std_logic_vector( AP+AP,ROMDATA_W ), conv_std_logic_vector( AP+AP+AP,ROMDATA_W ), conv_std_logic_vector( AP,ROMDATA_W ), conv_std_logic_vector( AP+AP,ROMDATA_W ), conv_std_logic_vector( AP+AP,ROMDATA_W ), conv_std_logic_vector( AP+AP+AP,ROMDATA_W ), conv_std_logic_vector( AP+AP,ROMDATA_W ), conv_std_logic_vector( AP+AP+AP,ROMDATA_W ), conv_std_logic_vector( AP+AP+AP,ROMDATA_W ), conv_std_logic_vector( AP+AP+AP+AP,ROMDATA_W ), (others => '0'), conv_std_logic_vector( BM,ROMDATA_W ), conv_std_logic_vector( CM,ROMDATA_W ), conv_std_logic_vector( CM+BM,ROMDATA_W ), conv_std_logic_vector( CP,ROMDATA_W ), conv_std_logic_vector( CP+BM,ROMDATA_W ), (others => '0'), conv_std_logic_vector( BM,ROMDATA_W ), conv_std_logic_vector( BP,ROMDATA_W ), (others => '0'), conv_std_logic_vector( BP+CM,ROMDATA_W ), conv_std_logic_vector( CM,ROMDATA_W ), conv_std_logic_vector( BP+CP,ROMDATA_W ), conv_std_logic_vector( CP,ROMDATA_W ), conv_std_logic_vector( BP,ROMDATA_W ), (others => '0'), (others => '0'), conv_std_logic_vector( AP,ROMDATA_W ), conv_std_logic_vector( AM,ROMDATA_W ), (others => '0'), conv_std_logic_vector( AM,ROMDATA_W ), (others => '0'), conv_std_logic_vector( AM+AM,ROMDATA_W ), conv_std_logic_vector( AM,ROMDATA_W ), conv_std_logic_vector( AP,ROMDATA_W ), conv_std_logic_vector( AP+AP,ROMDATA_W ), (others => '0'), conv_std_logic_vector( AP,ROMDATA_W ), (others => '0'), conv_std_logic_vector( AP,ROMDATA_W ), conv_std_logic_vector( AM,ROMDATA_W ), (others => '0'), (others => '0'), conv_std_logic_vector( CM,ROMDATA_W ), conv_std_logic_vector( BP,ROMDATA_W ), conv_std_logic_vector( BP+CM,ROMDATA_W ), conv_std_logic_vector( BM,ROMDATA_W ), conv_std_logic_vector( BM+CM,ROMDATA_W ), (others => '0'), conv_std_logic_vector( CM,ROMDATA_W ), conv_std_logic_vector( CP,ROMDATA_W ), (others => '0'), conv_std_logic_vector( CP+BP,ROMDATA_W ), conv_std_logic_vector( BP,ROMDATA_W ), conv_std_logic_vector( CP+BM,ROMDATA_W ), conv_std_logic_vector( BM,ROMDATA_W ), conv_std_logic_vector( CP,ROMDATA_W ), (others => '0') ); begin process(clk) begin if clk = '1' and clk'event then datao <= rom(CONV_INTEGER(UNSIGNED(addr)) ); end if; end process; end RTL;
The constant values are AP:1448,BP:1892,CP:784,DP:2009,EP:1703,FP:1138,GP: 400,AM:-1448,BM:-1892,CM:-784,DM:-2009,EM:-1703,FM:-1138,GM:-400. I run the testbench to see the output. However, I do not understand how they build the ROME and ROMO table. How they manage 6 bits address with the constant value? I try to write back the table with address and the constant values at a paper, but I still don't get it. As I know, they splits the constant into odd and even values and build the table. I really need help from anyone expert here http://www.edaboard.com/images/smilies/icon_sad.gif . Very appreciate your help. Thank in advance
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm sorry you code is extremely difficult to read. Could you repost it with newlines? In any case, it seems to use the (bad) conv_std_logic_vector function a lot...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- I'm sorry you code is extremely difficult to read. Could you repost it with newlines? In any case, it seems to use the (bad) conv_std_logic_vector function a lot... --- Quote End --- Hai Daixiwen, Below is the code,hope you can help. Thanks in advance.
-- 5:0
-- 5:4 = select matrix row (1 out of 4)
-- 3:0 = select precomputed MAC ( 1 out of 16)
library IEEE;
use IEEE.STD_LOGIC_1164.all;
-- use ieee.STD_LOGIC_signed.all;
use IEEE.STD_LOGIC_arith.all;
use WORK.MDCT_PKG.all;
entity ROMO is
port(
addr : in STD_LOGIC_VECTOR(ROMADDR_W-1 downto 0);
clk : in STD_LOGIC;
datao : out STD_LOGIC_VECTOR(ROMDATA_W-1 downto 0)
);
end ROMO;
architecture RTL of ROMO is
type ROM_TYPE is array (0 to 2**ROMADDR_W-1)
of STD_LOGIC_VECTOR(ROMDATA_W-1 downto 0);
constant rom : ROM_TYPE :=
(
(others => '0'),
conv_std_logic_vector( GP,ROMDATA_W ),
conv_std_logic_vector( FP,ROMDATA_W ),
conv_std_logic_vector( FP+GP,ROMDATA_W ),
conv_std_logic_vector( EP,ROMDATA_W ),
conv_std_logic_vector( EP+GP,ROMDATA_W ),
conv_std_logic_vector( EP+FP,ROMDATA_W ),
conv_std_logic_vector( EP+FP+GP,ROMDATA_W ),
conv_std_logic_vector( DP,ROMDATA_W ),
conv_std_logic_vector( DP+GP,ROMDATA_W ),
conv_std_logic_vector( DP+FP,ROMDATA_W ),
conv_std_logic_vector( DP+FP+GP,ROMDATA_W ),
conv_std_logic_vector( DP+EP,ROMDATA_W ),
conv_std_logic_vector( DP+EP+GP,ROMDATA_W ),
conv_std_logic_vector( DP+EP+FP,ROMDATA_W ),
conv_std_logic_vector( DP+EP+FP+GP,ROMDATA_W ),
(others => '0'),
conv_std_logic_vector( FM,ROMDATA_W ),
conv_std_logic_vector( DM,ROMDATA_W ),
conv_std_logic_vector( DM+FM,ROMDATA_W ),
conv_std_logic_vector( GM,ROMDATA_W ),
conv_std_logic_vector( GM+FM,ROMDATA_W ),
conv_std_logic_vector( GM+DM,ROMDATA_W ),
conv_std_logic_vector( GM+DM+FM,ROMDATA_W ),
conv_std_logic_vector( EP,ROMDATA_W ),
conv_std_logic_vector( EP+FM,ROMDATA_W ),
conv_std_logic_vector( EP+DM,ROMDATA_W ),
conv_std_logic_vector( EP+DM+FM,ROMDATA_W ),
conv_std_logic_vector( EP+GM,ROMDATA_W ),
conv_std_logic_vector( EP+GM+FM,ROMDATA_W ),
conv_std_logic_vector( EP+GM+DM,ROMDATA_W ),
conv_std_logic_vector( EP+GM+DM+FM,ROMDATA_W ),
(others => '0'),
conv_std_logic_vector( EP,ROMDATA_W ),
conv_std_logic_vector( GP,ROMDATA_W ),
conv_std_logic_vector( EP+GP,ROMDATA_W ),
conv_std_logic_vector( DM,ROMDATA_W ),
conv_std_logic_vector( DM+EP,ROMDATA_W ),
conv_std_logic_vector( DM+GP,ROMDATA_W ),
conv_std_logic_vector( DM+GP+EP,ROMDATA_W ),
conv_std_logic_vector( FP,ROMDATA_W ),
conv_std_logic_vector( FP+EP,ROMDATA_W ),
conv_std_logic_vector( FP+GP,ROMDATA_W ),
conv_std_logic_vector( FP+GP+EP,ROMDATA_W ),
conv_std_logic_vector( FP+DM,ROMDATA_W ),
conv_std_logic_vector( FP+DM+EP,ROMDATA_W ),
conv_std_logic_vector( FP+DM+GP,ROMDATA_W ),
conv_std_logic_vector( FP+DM+GP+EP,ROMDATA_W ),
(others => '0'),
conv_std_logic_vector( DM,ROMDATA_W ),
conv_std_logic_vector( EP,ROMDATA_W ),
conv_std_logic_vector( EP+DM,ROMDATA_W ),
conv_std_logic_vector( FM,ROMDATA_W ),
conv_std_logic_vector( FM+DM,ROMDATA_W ),
conv_std_logic_vector( FM+EP,ROMDATA_W ),
conv_std_logic_vector( FM+EP+DM,ROMDATA_W ),
conv_std_logic_vector( GP,ROMDATA_W ),
conv_std_logic_vector( GP+DM,ROMDATA_W ),
conv_std_logic_vector( GP+EP,ROMDATA_W ),
conv_std_logic_vector( GP+EP+DM,ROMDATA_W ),
conv_std_logic_vector( GP+FM,ROMDATA_W ),
conv_std_logic_vector( GP+FM+DM,ROMDATA_W ),
conv_std_logic_vector( GP+FM+EP,ROMDATA_W ),
conv_std_logic_vector( GP+FM+EP+DM,ROMDATA_W )
);
begin
process(clk)
begin
if clk = '1' and clk'event then
datao <= rom( CONV_INTEGER(UNSIGNED(addr)) );
end if;
end process;
end RTL;
-- 5:0
-- 5:4 = select matrix row (1 out of 4)
-- 3:0 = select precomputed MAC ( 1 out of 16)
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_arith.all;
use WORK.MDCT_PKG.all;
entity ROME is
port(
addr : in STD_LOGIC_VECTOR(ROMADDR_W-1 downto 0);
clk : in STD_LOGIC;
datao : out STD_LOGIC_VECTOR(ROMDATA_W-1 downto 0)
);
end ROME;
architecture RTL of ROME is
type ROM_TYPE is array (0 to (2**ROMADDR_W)-1)
of STD_LOGIC_VECTOR(ROMDATA_W-1 downto 0);
constant rom : ROM_TYPE :=
(
(others => '0'),
conv_std_logic_vector( AP,ROMDATA_W ),
conv_std_logic_vector( AP,ROMDATA_W ),
conv_std_logic_vector( AP+AP,ROMDATA_W ),
conv_std_logic_vector( AP,ROMDATA_W ),
conv_std_logic_vector( AP+AP,ROMDATA_W ),
conv_std_logic_vector( AP+AP,ROMDATA_W ),
conv_std_logic_vector( AP+AP+AP,ROMDATA_W ),
conv_std_logic_vector( AP,ROMDATA_W ),
conv_std_logic_vector( AP+AP,ROMDATA_W ),
conv_std_logic_vector( AP+AP,ROMDATA_W ),
conv_std_logic_vector( AP+AP+AP,ROMDATA_W ),
conv_std_logic_vector( AP+AP,ROMDATA_W ),
conv_std_logic_vector( AP+AP+AP,ROMDATA_W ),
conv_std_logic_vector( AP+AP+AP,ROMDATA_W ),
conv_std_logic_vector( AP+AP+AP+AP,ROMDATA_W ),
(others => '0'),
conv_std_logic_vector( BM,ROMDATA_W ),
conv_std_logic_vector( CM,ROMDATA_W ),
conv_std_logic_vector( CM+BM,ROMDATA_W ),
conv_std_logic_vector( CP,ROMDATA_W ),
conv_std_logic_vector( CP+BM,ROMDATA_W ),
(others => '0'),
conv_std_logic_vector( BM,ROMDATA_W ),
conv_std_logic_vector( BP,ROMDATA_W ),
(others => '0'),
conv_std_logic_vector( BP+CM,ROMDATA_W ),
conv_std_logic_vector( CM,ROMDATA_W ),
conv_std_logic_vector( BP+CP,ROMDATA_W ),
conv_std_logic_vector( CP,ROMDATA_W ),
conv_std_logic_vector( BP,ROMDATA_W ),
(others => '0'),
(others => '0'),
conv_std_logic_vector( AP,ROMDATA_W ),
conv_std_logic_vector( AM,ROMDATA_W ),
(others => '0'),
conv_std_logic_vector( AM,ROMDATA_W ),
(others => '0'),
conv_std_logic_vector( AM+AM,ROMDATA_W ),
conv_std_logic_vector( AM,ROMDATA_W ),
conv_std_logic_vector( AP,ROMDATA_W ),
conv_std_logic_vector( AP+AP,ROMDATA_W ),
(others => '0'),
conv_std_logic_vector( AP,ROMDATA_W ),
(others => '0'),
conv_std_logic_vector( AP,ROMDATA_W ),
conv_std_logic_vector( AM,ROMDATA_W ),
(others => '0'),
(others => '0'),
conv_std_logic_vector( CM,ROMDATA_W ),
conv_std_logic_vector( BP,ROMDATA_W ),
conv_std_logic_vector( BP+CM,ROMDATA_W ),
conv_std_logic_vector( BM,ROMDATA_W ),
conv_std_logic_vector( BM+CM,ROMDATA_W ),
(others => '0'),
conv_std_logic_vector( CM,ROMDATA_W ),
conv_std_logic_vector( CP,ROMDATA_W ),
(others => '0'),
conv_std_logic_vector( CP+BP,ROMDATA_W ),
conv_std_logic_vector( BP,ROMDATA_W ),
conv_std_logic_vector( CP+BM,ROMDATA_W ),
conv_std_logic_vector( BM,ROMDATA_W ),
conv_std_logic_vector( CP,ROMDATA_W ),
(others => '0')
);
begin
process(clk)
begin
if clk = '1' and clk'event then
datao <= rom(CONV_INTEGER(UNSIGNED(addr)) );
end if;
end process;
end RTL;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The question isn't clear. The ROM instances itself don't know about odd or even address, it's a matter how you connect address and data line externally, which isn't shown in your post.
Ignorant question: why do you think to need to split the ROM in odd and even at all? For hardware processors, odd and even are used when e.g. two 8-bit ROMs are connected to a 16-bit databus. This won't be necessary in FPGA where you can define a 16-bit ROM directly.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Ignorant question: why do you think to need to split the ROM in odd and even at all? For hardware processors, odd and even are used when e.g. two 8-bit ROMs are connected to a 16-bit databus. This won't be necessary in FPGA where you can define a 16-bit ROM directly. --- Quote End --- Hai FvM, Actually I get the code in open source and I don't know why the ROM is splits to odd and even. That is the exact question that I try to ask. I build the ROM table refer to the code, but I don't understand how they manage the input address with the constant value. However, how to build the ROM table if I have eight constant values that will be multiply with eight input data? Is it not necessary if I split the constant to two ROM table (4 constant each ROM)?.. Thanks in advance
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How are those ROMs instantiated in the higher level component? If you want to write back a table with the input => output assignments in each ROM, you just need to read the data values in the order they are listed (and remember that (others => '0') means a data vector with all zeros). For example for ROMO:
addr data 000000 0 000001 GP 000010 FP 000011 FP+GP 000100 EP 000101 EP+GP 000110 EP+FP 000111 EP+FP+GP 001000 DP 001001 DP+GP 001010 DP+FP 001011 DP+FP+GP 001100 DP+EP 001101 DP+EP+GP 001110 DP+EP+FP 001111 DP+EP+FP+GP 010000 0 010001 FM 010010 DM etc... That said, I think you could replace those ROMs by the actual arithmetic operations they are supposed to accelerate. The synthesizer should be smart enough to optimize this and I'm not sure that using a ROM block for that is actually a good optimization.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hai Daixiwen,
Actually I want to create a ROM table with 8 constant values. All the constant values are in fixed point number (0.123,0.871,-0.99,..etc). In the main project, an input of std_logic_vector (7 downto 0) is used as an address for the ROM. Out of the topic, how to convert the fixed point number to std_logic_vector? Thanks in advance- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can use the same principle and do the conversion from constant float to integer by doing a multiplication in each assignment, but if you have some time I'd suggest to use the new VHDL fixed point signed type. Then you can directly use those values and your code will be a lot easier to read.
This type isn't officially supported in Quartus yet, but you can use a compatibility library and then use the type in your VHDL files. Have a look at this thread (http://www.alteraforum.com/forum/showthread.php?t=36362) for more information.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hai Daixiwen,
I use to_slv function to convert the floating point to std_logic_vector type. Btw, thanks for your helps :)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page