I want a RAM in VHDL (that can synth开发者_开发问答esize on Xilinx, Altera..) with the following 'catch' -
I must write to it block-wise and read from it bit-wise.
How do I achieve this?
You should just read from the RAM block wise, and shift out the vector that you read out to get it bit-wise.
For example, if ram_do is the vector that you read out then just shift out the bits 1 at a time using ram_data <= '0' & ram_data(9 downto 1)
, where ram_data(0) is the bitwise value that you can take per clock cycle.
The hardware you will get is a RAM plus a shift register.
You can instantiate a vendor specific ram block which works this way.
Or, you can infer one with some synthesis tools. For example, XST allows this (see page 201 onwards of UG687 for code examples, just please change the sample code to use numeric_std.all
!) I have no idea if this method is portable to Altera's Quartus though.
You should read the section Mixed-Width Dual-Port RAM in Recommended HDL Coding Style (Altera Quartus manual). I am not sure how portable this code is, but the following example show how this can be done on Altera devices:
library ieee;
use ieee.std_logic_1164.all;
package ram_types is
type word_t is array (0 to 3) of std_logic_vector(7 downto 0);
type ram_t is array (0 to 255) of word_t;
end ram_types;
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.ram_types.all;
entity mixed_width_ram is
port (
we, clk : in std_logic;
waddr : in integer range 0 to 255;
wdata : in word_t;
rdata : in integer range 0 to 1023;
q : out std_llgic_vector(7 downto 0));
end mixed_width_ram;
architecture rtl of mixed_width_ram is
signal ram : ram_t;
begin -- rtl
process(clk, we)
begin
if (rising_edge(clk)) then
if(we = '1') then
ram(waddr) <= wdata;
end if;
q <= ram(raddr / 4 )(raddr mod 4);
end if;
end process;
end rtl;
精彩评论