Standardized fifo type adn full test debugging
This commit is contained in:
parent
241fe60024
commit
6a6ebdef95
@ -54,7 +54,13 @@ begin
|
||||
'1',
|
||||
NO_OP);
|
||||
else
|
||||
state.ready <= not ored;
|
||||
-- Make sure to tell the management unit instruction is done
|
||||
if ored = '0' and state.ready = '0' then
|
||||
controller_to_manager.done <= '1';
|
||||
state.ready <= '1';
|
||||
else
|
||||
controller_to_manager.done <= '0';
|
||||
end if;
|
||||
if ored = '0' then
|
||||
state.address <= manager_to_controller.address;
|
||||
state.seq_mem_access_count <= manager_to_controller.seq_mem_access_count;
|
||||
|
||||
@ -9,18 +9,13 @@ use techmap.gencomp.all;
|
||||
|
||||
entity fifo_buffer is
|
||||
generic (
|
||||
data_width : natural := 8;
|
||||
buffer_size : natural := 64;
|
||||
tech : integer := nx
|
||||
tech : integer := 0
|
||||
);
|
||||
port (
|
||||
clk, rst : in std_logic;
|
||||
ready_in : in std_logic;
|
||||
ready_out : out std_logic;
|
||||
valid_in : in std_logic;
|
||||
valid_out : out std_logic;
|
||||
data_in : in std_logic_vector(data_width - 1 downto 0);
|
||||
data_out : out std_logic_vector(data_width - 1 downto 0)
|
||||
rst, in_clk, out_clk : in std_logic;
|
||||
fifo_in : in fifo_interface_t;
|
||||
fifo_out : out fifo_interface_t
|
||||
);
|
||||
end entity fifo_buffer;
|
||||
|
||||
@ -28,8 +23,8 @@ architecture rtl of fifo_buffer is
|
||||
constant address_bits : natural := integer(ceil(log2(real(buffer_size))));
|
||||
signal read_pointer : std_logic_vector(address_bits - 1 downto 0);
|
||||
signal write_pointer : std_logic_vector(address_bits - 1 downto 0);
|
||||
signal data_out_signal : std_logic_vector(data_width - 1 downto 0);
|
||||
signal data_in_signal : std_logic_vector(data_width - 1 downto 0);
|
||||
signal data_out_signal : std_logic_vector(fifo_width - 1 downto 0);
|
||||
signal data_in_signal : std_logic_vector(fifo_width - 1 downto 0);
|
||||
signal write_signal : std_logic;
|
||||
signal buffer_full : std_logic;
|
||||
signal buffer_empty : std_logic;
|
||||
@ -54,25 +49,27 @@ begin
|
||||
techmap_ram_inst : entity techmap.syncram_2p
|
||||
generic map(tech => tech,
|
||||
abits => address_bits,
|
||||
dbits => data_width
|
||||
dbits => fifo_width
|
||||
)
|
||||
port map(
|
||||
rclk => clk,
|
||||
rclk => out_clk,
|
||||
renable => '1',
|
||||
raddress => read_pointer,
|
||||
dataout => data_out_signal,
|
||||
wclk => clk,
|
||||
wclk => in_clk,
|
||||
write => write_signal,
|
||||
waddress => write_pointer,
|
||||
datain => data_in_signal,
|
||||
customclk => clk,
|
||||
customclk => in_clk, --NOTE: No clue what this does but it has to be set to something
|
||||
customout => customout
|
||||
);
|
||||
|
||||
data_in_signal <= fifo_in.data;
|
||||
fifo_out.data <= data_out_signal;
|
||||
comb_proc: process(write_pointer, read_pointer)
|
||||
variable write_pointer_inc : unsigned(address_bits - 1 downto 0) := unsigned(write_pointer);
|
||||
variable write_pointer_inc : unsigned(address_bits - 1 downto 0);
|
||||
begin
|
||||
ready_out <= '1';
|
||||
fifo_out.ready <= not buffer_full;
|
||||
write_pointer_inc := unsigned(write_pointer) + 1;
|
||||
customout <= "0";
|
||||
if write_pointer_inc = unsigned(read_pointer) then
|
||||
@ -88,35 +85,29 @@ begin
|
||||
end if;
|
||||
end process comb_proc;
|
||||
|
||||
seq_proc: process(rst, clk)
|
||||
seq_proc: process(rst, fifo_in)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
ready_out <= '0';
|
||||
valid_out <= '0';
|
||||
if rst = '1' then
|
||||
fifo_out.valid <= '0';
|
||||
read_pointer <= (others => '0');
|
||||
write_pointer <= (others => '0');
|
||||
data_in_signal <= (others => '0');
|
||||
data_out_signal <= (others => '0');
|
||||
write_signal <= '0';
|
||||
buffer_full <= '0';
|
||||
elsif rising_edge(in_clk) then
|
||||
if fifo_in.valid = '1' and buffer_full = '0' then
|
||||
write_signal <= '1';
|
||||
write_pointer <= std_logic_vector(unsigned(write_pointer) + 1);
|
||||
else
|
||||
if ready_in = '1' and buffer_empty = '0' then
|
||||
data_out <= data_out_signal;
|
||||
valid_out <= '1';
|
||||
read_pointer <= std_logic_vector(unsigned(read_pointer) + 1);
|
||||
else
|
||||
valid_out <= '0';
|
||||
data_out <= (others => '0');
|
||||
end if;
|
||||
if valid_in = '1' then
|
||||
data_in_signal <= data_in;
|
||||
write_signal <= '1';
|
||||
write_pointer <= std_logic_vector(unsigned(write_pointer) + 1);
|
||||
else
|
||||
write_signal <= '0';
|
||||
data_in_signal <= (others => '0');
|
||||
end if;
|
||||
write_signal <= '0';
|
||||
end if;
|
||||
end if;
|
||||
if rising_edge(out_clk) and rst = '0' then
|
||||
if fifo_in.ready = '1' and buffer_empty = '0' then
|
||||
fifo_out.valid <= '1';
|
||||
read_pointer <= std_logic_vector(unsigned(read_pointer) + 1);
|
||||
write_signal <= '1';
|
||||
else
|
||||
fifo_out.valid <= '0';
|
||||
write_signal <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process seq_proc;
|
||||
|
||||
@ -27,8 +27,9 @@ architecture rtl of ganimede_toplevel is
|
||||
signal controller_to_manager : controller_to_manager_t;
|
||||
signal socbridge_driver_to_manager : socbridge_driver_to_manager_t;
|
||||
signal manager_to_socbridge_driver : manager_to_socbridge_driver_t;
|
||||
signal socbridge_driver_to_buffer : socbridge_driver_to_ip_t;
|
||||
signal buffer_to_socbridge_driver : ip_to_socbridge_driver_t; --TODO determine where we want to declare the IP
|
||||
signal socbridge_driver_to_buffer : fifo_interface_t;
|
||||
signal buffer_to_socbridge_driver : fifo_interface_t;
|
||||
signal socbridge_clk : std_logic;
|
||||
|
||||
--signal gan_socbridge_WE_in : std_logic;
|
||||
--signal gan_socbridge_WE_out : std_logic;
|
||||
@ -42,6 +43,7 @@ begin
|
||||
socbridge_driver_inst: entity gan_socbridge.socbridge_driver
|
||||
port map(
|
||||
clk => clk,
|
||||
socbridge_clk => socbridge_clk,
|
||||
rst => rst,
|
||||
controller_to_socbridge_driver => controller_to_drivers.socbridge,
|
||||
socbridge_driver_to_controller => drivers_to_controller.socbridge,
|
||||
@ -49,8 +51,8 @@ begin
|
||||
socbridge_driver_to_manager => socbridge_driver_to_manager,
|
||||
ext_to_socbridge_driver => ext_to_ganimede.socbridge,
|
||||
socbridge_driver_to_ext => ganimede_to_ext.socbridge,
|
||||
ip_to_socbridge_driver => ip_to_ganimede.socbridge,
|
||||
socbridge_driver_to_ip => ganimede_to_ip.socbridge
|
||||
ip_to_socbridge_driver => buffer_to_socbridge_driver,
|
||||
socbridge_driver_to_ip => socbridge_driver_to_buffer
|
||||
);
|
||||
|
||||
controller_inst: entity gan_controller.control_unit
|
||||
@ -75,26 +77,20 @@ begin
|
||||
|
||||
fifo_buffer_to_ip_inst : entity gan_buffer.fifo_buffer
|
||||
port map(
|
||||
clk => clk,
|
||||
in_clk => socbridge_clk, --TODO wrong clock
|
||||
out_clk => clk,
|
||||
rst => rst,
|
||||
ready_in => ip_to_ganimede.socbridge.ready,
|
||||
ready_out => buffer_to_socbridge_driver.ready,
|
||||
valid_in => socbridge_driver_to_buffer.valid,
|
||||
valid_out => ganimede_to_ip.socbridge.valid,
|
||||
data_in => socbridge_driver_to_buffer.payload,
|
||||
data_out => ganimede_to_ip.socbridge.payload
|
||||
fifo_in => socbridge_driver_to_buffer,
|
||||
fifo_out => ganimede_to_ip.socbridge
|
||||
);
|
||||
|
||||
fifo_buffer_from_ip_inst : entity gan_buffer.fifo_buffer
|
||||
port map(
|
||||
clk => clk,
|
||||
in_clk => clk,
|
||||
out_clk => clk,
|
||||
rst => rst,
|
||||
ready_in => socbridge_driver_to_buffer.ready,
|
||||
ready_out => ganimede_to_ip.socbridge.ready,
|
||||
valid_in => ip_to_ganimede.socbridge.valid,
|
||||
valid_out => buffer_to_socbridge_driver.valid,
|
||||
data_in => ip_to_ganimede.socbridge.payload,
|
||||
data_out => buffer_to_socbridge_driver.payload
|
||||
fifo_in => ip_to_ganimede.socbridge,
|
||||
fifo_out => buffer_to_socbridge_driver
|
||||
);
|
||||
--- LATER WE ADD OPTIMIZATIONS HERE ---
|
||||
|
||||
|
||||
@ -8,10 +8,16 @@ package io_types is
|
||||
constant number_of_drivers : natural := 1;
|
||||
constant address_width : natural := 32;
|
||||
constant inst_word_width : natural := 2;
|
||||
constant fifo_width : natural := 8;
|
||||
|
||||
--- STANDARD TYPES ---
|
||||
type instruction_command_t is (NO_OP, READ, WRITE);
|
||||
|
||||
type fifo_interface_t is record
|
||||
ready, valid : std_logic;
|
||||
data : std_logic_vector(fifo_width - 1 downto 0);
|
||||
end record fifo_interface_t;
|
||||
|
||||
type ext_protocol_def_t is record
|
||||
name: string (1 to 20);
|
||||
payload_width : natural;
|
||||
@ -31,7 +37,7 @@ package io_types is
|
||||
end record manager_to_controller_t;
|
||||
|
||||
type controller_to_manager_t is record
|
||||
ready : std_logic;
|
||||
ready, done : std_logic;
|
||||
end record controller_to_manager_t;
|
||||
|
||||
--- PROTOCOL INFORMATION ---
|
||||
@ -61,15 +67,9 @@ package io_types is
|
||||
control : STD_LOGIC_VECTOR(interface_inst.socbridge.control_width_in - 1 downto 0);
|
||||
end record socbridge_driver_to_ext_t;
|
||||
|
||||
type socbridge_driver_to_ip_t is record
|
||||
payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0);
|
||||
ready, valid : std_logic;
|
||||
end record socbridge_driver_to_ip_t;
|
||||
subtype socbridge_driver_to_ip_t is fifo_interface_t;
|
||||
|
||||
type ip_to_socbridge_driver_t is record
|
||||
payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0);
|
||||
ready, valid : std_logic;
|
||||
end record ip_to_socbridge_driver_t;
|
||||
subtype ip_to_socbridge_driver_t is fifo_interface_t;
|
||||
|
||||
type controller_to_drivers_t is record
|
||||
socbridge : controller_to_socbridge_driver_t;
|
||||
|
||||
@ -24,6 +24,7 @@ architecture rtl of management_unit is
|
||||
signal read_address : manager_word_t;
|
||||
-- Address indexing whole words, not bytes
|
||||
signal word_address : natural;
|
||||
signal cmd : std_logic_vector(1 downto 0);
|
||||
|
||||
function pack(word: manager_word_t) return std_logic_vector is
|
||||
begin
|
||||
@ -41,20 +42,19 @@ architecture rtl of management_unit is
|
||||
|
||||
begin
|
||||
|
||||
|
||||
read_address <= manager_state.memory(0);
|
||||
write_address <= manager_state.memory(1);
|
||||
|
||||
|
||||
comb_proc: process(controller_to_manager, socbridge_driver_to_manager,manager_state)
|
||||
variable local_word_address : natural;
|
||||
begin
|
||||
local_word_address := to_integer(shift_right(unsigned(socbridge_driver_to_manager.address and address_mask), address_shift));
|
||||
local_word_address := to_integer(shift_right(unsigned(socbridge_driver_to_manager.address), address_shift)) mod mem_words;
|
||||
-- Read data from manager to SoCBridge driver
|
||||
manager_to_socbridge_driver.ready <= '1';
|
||||
manager_to_socbridge_driver.data <= pack(manager_state.memory(local_word_address));
|
||||
manager_to_socbridge_driver.valid <= '1';
|
||||
word_address <= local_word_address;
|
||||
manager_to_controller.cmd <= cmd;
|
||||
end process comb_proc;
|
||||
|
||||
-- tre sorters sätt att avsluta en skrivning:
|
||||
@ -77,24 +77,32 @@ begin
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- Is the controller done executing an instruction
|
||||
if controller_to_manager.done = '1' then
|
||||
if cmd = "10" then
|
||||
manager_state.memory(0) <= manager_word_reset_val;
|
||||
elsif cmd = "01" then
|
||||
manager_state.memory(1) <= manager_word_reset_val;
|
||||
end if;
|
||||
end if;
|
||||
-- Is there a read instruction in memory
|
||||
if pack(read_address) /= empty_word and controller_to_manager.ready = '1' then
|
||||
manager_to_controller.address <= read_address.address & "0000000000";
|
||||
manager_to_controller.driver_id <= "1"; -- Only supprts one driver at present
|
||||
manager_to_controller.seq_mem_access_count <= 2**to_integer(unsigned(read_address.size)) * 2**10;
|
||||
manager_to_controller.cmd <= "10";
|
||||
cmd <= "10";
|
||||
-- Is there a write instruction in memory
|
||||
elsif pack(write_address) /= empty_word and controller_to_manager.ready = '1' then
|
||||
manager_to_controller.address <= write_address.address & "0000000000";
|
||||
manager_to_controller.driver_id <= "1"; -- Only supports one driver at present
|
||||
manager_to_controller.seq_mem_access_count <= 2**to_integer(unsigned(read_address.size)) * 2**10;
|
||||
manager_to_controller.cmd <= "01";
|
||||
cmd <= "01";
|
||||
else
|
||||
-- No instruction present in memory, all zeroes to control unit
|
||||
manager_to_controller.address <= (others => '0');
|
||||
manager_to_controller.driver_id <= "0"; -- Only supprts one driver at present
|
||||
manager_to_controller.seq_mem_access_count <= 0;
|
||||
manager_to_controller.cmd <= "00";
|
||||
cmd <= "00";
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
@ -15,7 +15,7 @@ architecture tb of management_unit_tb is
|
||||
signal rst : std_logic;
|
||||
|
||||
signal manager_to_controller : manager_to_controller_t;
|
||||
signal controller_to_manager : controller_to_manager_t := (ready => '0');
|
||||
signal controller_to_manager : controller_to_manager_t := (ready => '0', done => '0');
|
||||
signal socbridge_driver_to_manager : socbridge_driver_to_manager_t := (
|
||||
address => (others => '0'),
|
||||
data => (others => '0'),
|
||||
|
||||
@ -16,6 +16,7 @@ entity socbridge_driver is
|
||||
port(
|
||||
clk : in std_logic;
|
||||
rst : in std_logic;
|
||||
socbridge_clk : out std_logic;
|
||||
controller_to_socbridge_driver : in controller_to_socbridge_driver_t;
|
||||
socbridge_driver_to_controller : out socbridge_driver_to_controller_t;
|
||||
manager_to_socbridge_driver : in manager_to_socbridge_driver_t;
|
||||
@ -48,6 +49,7 @@ begin
|
||||
ext_to_socbridge_driver_rec.data <= ext_to_socbridge_driver.payload;
|
||||
ext_to_socbridge_driver_rec.clk <= ext_to_socbridge_driver.control(1);
|
||||
ext_to_socbridge_driver_rec.parity <= ext_to_socbridge_driver.control(0);
|
||||
socbridge_clk <= ext_to_socbridge_driver_rec.clk;
|
||||
|
||||
comb_proc: process(ext_to_socbridge_driver, ip_to_socbridge_driver,
|
||||
st, controller_to_socbridge_driver, trans_st,
|
||||
@ -214,7 +216,7 @@ begin
|
||||
local_next_data_out := (others => '0');
|
||||
socbridge_driver_to_ip.ready <= '0';
|
||||
socbridge_driver_to_ip.valid <= '0';
|
||||
socbridge_driver_to_ip.payload <= (others => '0');
|
||||
socbridge_driver_to_ip.data <= (others => '0');
|
||||
--- ### TX_STATE BASED OUTPUT ### ---
|
||||
case st.curr_tx_state is
|
||||
when IDLE =>
|
||||
@ -227,7 +229,7 @@ begin
|
||||
when TX_W_BODY =>
|
||||
if st.tx_stage > 0 then
|
||||
socbridge_driver_to_ip.ready <= '1';
|
||||
local_next_data_out := ip_to_socbridge_driver.payload;
|
||||
local_next_data_out := ip_to_socbridge_driver.data;
|
||||
end if;
|
||||
when TX_R_BODY =>
|
||||
if st.tx_stage > 0 then
|
||||
@ -252,7 +254,7 @@ begin
|
||||
when RX_HEADER =>
|
||||
when RX_W_BODY =>
|
||||
when RX_R_BODY =>
|
||||
socbridge_driver_to_ip.payload <= st.ext_to_socbridge_driver_reg.data;
|
||||
socbridge_driver_to_ip.data <= st.ext_to_socbridge_driver_reg.data;
|
||||
socbridge_driver_to_ip.valid <= '1';
|
||||
when RX_AWAIT =>
|
||||
if st.curr_rx_transaction = WRITE or st.curr_rx_transaction = WRITE_ADD then
|
||||
|
||||
@ -99,7 +99,7 @@ begin
|
||||
|
||||
while not done loop
|
||||
wait until (rising_edge(socbridge_driver_to_ext.control(1)) or falling_edge(socbridge_driver_to_ext.control(1))) and socbridge_driver_to_ip.ready = '1';
|
||||
ip_to_socbridge_driver.payload <= std_logic_vector(to_unsigned(count, 8));
|
||||
ip_to_socbridge_driver.data <= std_logic_vector(to_unsigned(count, 8));
|
||||
count := count + 1;
|
||||
end loop;
|
||||
wait;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user