--=============================
-- Listing 15.24 fifo
--=============================
library ieee;
use ieee.std_logic_1164.all;
entity fifo_top_para is
generic(
B: natural:=3; -- number of bits
W: natural:=2; -- number of address bits
CNT_MODE: natural:=0 -- binary or LFSR
);
port(
clk, reset: in std_logic;
rd, wr: in std_logic;
w_data: in std_logic_vector (B-1 downto 0);
empty, full: out std_logic;
r_data: out std_logic_vector (B-1 downto 0)
);
end fifo_top_para;
architecture arch of fifo_top_para is
component fifo_sync_ctrl_para
generic(
N: natural;
CNT_MODE: natural
);
port(
clk, reset: in std_logic;
wr, rd: in std_logic;
full, empty: out std_logic;
w_addr, r_addr: out std_logic_vector(N-1 downto 0)
);
end component;
component reg_file_para
generic(
W: natural;
B: natural
);
port(
clk, reset: in std_logic;
wr_en: in std_logic;
w_data: in std_logic_vector(B-1 downto 0);
w_addr, r_addr: in std_logic_vector(W-1 downto 0);
r_data: out std_logic_vector(B-1 downto 0)
);
end component;
signal r_addr : std_logic_vector(W-1 downto 0);
signal w_addr : std_logic_vector(W-1 downto 0);
signal f_status, wr_fifo:std_logic;
begin
u_ctrl: fifo_sync_ctrl_para
generic map(N=>W, CNT_MODE=>CNT_MODE)
port map(clk=>clk, reset=>reset, wr=>wr, rd=>rd,
full=>f_status, empty=>empty,
w_addr=>w_addr, r_addr=>r_addr);
wr_fifo <= wr and (not f_status);
full <= f_status;
u_reg_file: reg_file_para
generic map(W=>W, B=>B)
port map(clk=>clk, reset=>reset, wr_en=>wr_fifo,
w_data=>w_data, w_addr=>w_addr,
r_addr=> r_addr, r_data => r_data);
end arch;
--=============================
-- Listing 15.25 fifo control
--=============================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity fifo_sync_ctrl_para is
generic(
N: natural;
CNT_MODE: natural
);
port(
clk, reset: in std_logic;
wr, rd: in std_logic;
full, empty: out std_logic;
w_addr, r_addr: out std_logic_vector(N-1 downto 0)
);
end fifo_sync_ctrl_para;
architecture lookahead_arch of fifo_sync_ctrl_para is
component lfsr_next is
generic(N: natural);
port(
q_in: in std_logic_vector(N-1 downto 0);
q_out: out std_logic_vector(N-1 downto 0)
);
end component;
constant LFSR_CTR: natural:=0;
signal w_ptr_reg, w_ptr_next, w_ptr_succ:
std_logic_vector(N-1 downto 0);
signal r_ptr_reg, r_ptr_next, r_ptr_succ:
std_logic_vector(N-1 downto 0);
signal full_reg, empty_reg, full_next, empty_next:
std_logic;
signal wr_op: std_logic_vector(1 downto 0);
begin
-- register for read and write pointers
process(clk,reset)
begin
if (reset='1') then
w_ptr_reg <= (others=>'0');
r_ptr_reg <= (others=>'0');
elsif (clk'event and clk='1') then
w_ptr_reg <= w_ptr_next;
r_ptr_reg <= r_ptr_next;
end if;
end process;
-- statue FF
process(clk,reset)
begin
if (reset='1') then
full_reg <= '0';
empty_reg <= '1';
elsif (clk'event and clk='1') then
full_reg <= full_next;
empty_reg <= empty_next;
end if;
end process;
-- successive value for LFSR counter
g_lfsr:
if (CNT_MODE=LFSR_CTR) generate
u_lfsr_wr: lfsr_next
generic map(N=>N)
port map(q_in=>w_ptr_reg, q_out=>w_ptr_succ);
u_lfsr_rd: lfsr_next
generic map(N=>N)
port map(q_in=>r_ptr_reg, q_out=>r_ptr_succ);
end generate;
-- successive value for binary counter
g_bin:
if (CNT_MODE/=LFSR_CTR) generate
w_ptr_succ <= std_logic_vector(unsigned(w_ptr_reg) + 1);
r_ptr_succ <= std_logic_vector(unsigned(r_ptr_reg) + 1);
end generate;
-- next-state logic for read and write pointers
wr_op <= wr & rd;
process(w_ptr_reg,w_ptr_succ,r_ptr_reg,r_ptr_succ,wr_op,
empty_reg,full_reg)
begin
w_ptr_next <= w_ptr_reg;
r_ptr_next <= r_ptr_reg;
full_next <= full_reg;
empty_next <= empty_reg;
case wr_op is
when "00" => -- no op
when "01" => -- read
if (empty_reg /= '1') then -- not empty
r_ptr_next <= r_ptr_succ;
full_next <= '0';
if (r_ptr_succ=w_ptr_reg) then
empty_next <='1';
end if;
end if;
when "10" => -- write
if (full_reg /= '1') then -- not full
w_ptr_next <= w_ptr_succ;
empty_next <= '0';
if (w_ptr_succ=r_ptr_reg) then
full_next <='1';
end if;
end if;
when others => -- write/read;
w_ptr_next <= w_ptr_succ;
r_ptr_next <= r_ptr_succ;
end case;
end process;
-- output
w_addr <= w_ptr_reg;
full <= full_reg;
r_addr <= r_ptr_reg;
empty <= empty_reg;
end lookahead_arch;
--=============================
-- Listing 15.27 lfsr next-state logic
--=============================
library ieee;
use ieee.std_logic_1164.all;
entity lfsr_next is
generic(N: natural);
port(
q_in: in std_logic_vector(N-1 downto 0);
q_out: out std_logic_vector(N-1 downto 0)
);
end lfsr_next;
architecture para_arch of lfsr_next is
constant MAX_N: natural:= 8;
type tap_array_type is
array(2 to MAX_N) of std_logic_vector(MAX_N-1 downto 0);
constant TAP_CONST_ARRAY: tap_array_type:=
(2 => (1|0=>'1', others=>'0'),
3 => (1|0=>'1', others=>'0'),
4 => (1|0=>'1', others=>'0'),
5 => (2|0=>'1', others=>'0'),
6 => (1|0=>'1', others=>'0'),
7 => (3|0=>'1', others=>'0'),
8 => (4|3|2|0=>'1', others=>'0'));
signal fb: std_logic;
begin
-- next-state logic
process(q_in)
constant TAP_CONST: std_logic_vector(MAX_N-1 downto 0)
:= TAP_CONST_ARRAY(N);
variable tmp: std_logic;
begin
tmp := '0';
for i in 0 to (N-1) loop
tmp := tmp xor (q_in(i) and TAP_CONST(i));
end loop;
fb <= not(tmp); -- exclude all 1's
end process;
q_out <= fb & q_in(N-1 downto 1) ;
end para_arch;
--=============================
-- Listing 15.27 lfsr next-state logic
--=============================
library ieee;
use ieee.std_logic_1164.all;
entity lfsr_next is
generic(N: natural);
port(
q_in: in std_logic_vector(N-1 downto 0);
q_out: out std_logic_vector(N-1 downto 0)
);
end lfsr_next;
architecture para_arch of lfsr_next is
constant MAX_N: natural:= 8;
type tap_array_type is
array(2 to MAX_N) of std_logic_vector(MAX_N-1 downto 0);
constant TAP_CONST_ARRAY: tap_array_type:=
(2 => (1|0=>'1', others=>'0'),
3 => (1|0=>'1', others=>'0'),
4 => (1|0=>'1', others=>'0'),
5 => (2|0=>'1', others=>'0'),
6 => (1|0=>'1', others=>'0'),
7 => (3|0=>'1', others=>'0'),
8 => (4|3|2|0=>'1', others=>'0'));
signal fb: std_logic;
begin
-- next-state logic
process(q_in)
constant TAP_CONST: std_logic_vector(MAX_N-1 downto 0)
:= TAP_CONST_ARRAY(N);
variable tmp: std_logic;
begin
tmp := '0';
for i in 0 to (N-1) loop
tmp := tmp xor (q_in(i) and TAP_CONST(i));
end loop;
fb <= not(tmp); -- exclude all 1's
end process;
q_out <= fb & q_in(N-1 downto 1) ;
end para_arch;
--=============================
-- Listing 15.25 register file
--=============================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.util_pkg.all;
entity reg_file_para is
generic(
W: natural;
B: natural
);
port(
clk, reset: in std_logic;
wr_en: in std_logic;
w_data: in std_logic_vector(B-1 downto 0);
w_addr, r_addr: in std_logic_vector(W-1 downto 0);
r_data: out std_logic_vector(B-1 downto 0)
);
end reg_file_para;
architecture str_arch of reg_file_para is
component mux2d is
generic(
P: natural; -- number of input ports
B: natural -- number of bits per port
);
port(
a: in std_logic_2d(P-1 downto 0, B-1 downto 0);
sel: in std_logic_vector(log2c(P)-1 downto 0);
y: out std_logic_vector(B-1 downto 0)
);
end component;
component tree_decoder is
generic(WIDTH: natural);
port(
a: in std_logic_vector(WIDTH-1 downto 0);
en: std_logic;
code: out std_logic_vector(2**WIDTH-1 downto 0)
);
end component;
constant W_SIZE: natural := 2**W;
type reg_file_type is array (2**W-1 downto 0) of
std_logic_vector(B-1 downto 0);
signal array_reg: reg_file_type;
signal array_next: reg_file_type;
signal array_2d: std_logic_2d(2**W-1 downto 0,B-1 downto 0);
signal en: std_logic_vector(2**W-1 downto 0);
begin
-- register array
process(clk,reset)
begin
if (reset='1') then
array_reg <= (others=>(others=>'0'));
elsif (clk'event and clk='1') then
array_reg <= array_next;
end if;
end process;
-- enable decoding logic for register array
u_bin_decoder: tree_decoder
generic map(WIDTH=>W)
port map(en=>wr_en, a=>w_addr, code=>en);
-- next-state logic of register file
process(array_reg,en,w_data)
begin
for i in (2**W-1) downto 0 loop
if en(i)='1' then
array_next(i) <= w_data;
else
array_next(i) <= array_reg(i);
end if;
end loop;
end process;
-- convert to std_logic_2d
process(array_reg)
begin
for r in (2**W-1) downto 0 loop
for c in 0 to (B-1) loop
array_2d(r,c)<=array_reg(r)(c);
end loop;
end loop;
end process;
-- read port multiplexing circuit
read_mux: mux2d
generic map(P=>2**W, B=>B)
port map(a=>array_2d, sel=>r_addr, y=>r_data);
end str_arch;
--=============================
-- Listing 15.26
--=============================
architecture beh_arch of reg_file_para is
type reg_file_type is array (2**W-1 downto 0) of
std_logic_vector(B-1 downto 0);
signal array_reg: reg_file_type;
signal array_next: reg_file_type;
begin
-- register array
process(clk,reset)
begin
if (reset='1') then
array_reg <= (others=>(others=>'0'));
elsif (clk'event and clk='1') then
array_reg <= array_next;
end if;
end process;
-- next-state logic for register array
process(array_reg,wr_en,w_addr,w_data)
begin
array_next <= array_reg;
if wr_en='1' then
array_next(to_integer(unsigned(w_addr))) <= w_data;
end if;
end process;
-- read port
r_data <= array_reg(to_integer(unsigned(r_addr)));
end beh_arch;
No comments:
Post a Comment