Standardized fifo type adn full test debugging

This commit is contained in:
Adam 2025-04-18 15:27:19 +02:00
parent 241fe60024
commit 6a6ebdef95
8 changed files with 84 additions and 81 deletions

View File

@ -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;

View File

@ -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,37 +85,31 @@ 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
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
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;
fifo_out.valid <= '0';
write_signal <= '0';
end if;
end if;
end process seq_proc;
end architecture rtl;

View File

@ -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 ---

View File

@ -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;

View File

@ -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;

View File

@ -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'),

View File

@ -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

View File

@ -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;