From 895b0242a38d2bc2ae8143602fa2c9d8c4d5eea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Mon, 17 Feb 2025 17:01:30 +0100 Subject: [PATCH 01/40] began working on ganimede template. Unconstrained types are no longer needed --- src/ganimede.vhd | 32 ++++++++++++++++++++++++++ src/io_type_pkg.vhd | 55 +++++++++++++++++++-------------------------- 2 files changed, 55 insertions(+), 32 deletions(-) create mode 100644 src/ganimede.vhd diff --git a/src/ganimede.vhd b/src/ganimede.vhd new file mode 100644 index 0000000..33eb20d --- /dev/null +++ b/src/ganimede.vhd @@ -0,0 +1,32 @@ +library IEEE; +use IEEE.std_logic_1164.all; +library work; +use work.io_types.all; + +entity ganimede is + port ( + ext_interface_in : in ext_interface_in_t; + ext_interface_out : out ext_interface_out_t + ); +end entity ganimede; +architecture rtl of ganimede is + --- SIGNALS INTERFACING THE IP CORE + signal int_interface_in : int_interface_in_t; + signal int_interface_out : int_interface_out_t; + + --- COMPONENT DECLERATIONS --- + component socbridge_driver is + port( + ext_in : in ext_socbridge_in_t; + ext_out : out ext_socbridge_out_t; + int_in : in int_socbridge_in_t; + int_out : out int_socbridge_out_t + ); + end component; + +begin + + + + +end architecture rtl; diff --git a/src/io_type_pkg.vhd b/src/io_type_pkg.vhd index 7f025df..48fda5e 100644 --- a/src/io_type_pkg.vhd +++ b/src/io_type_pkg.vhd @@ -5,15 +5,6 @@ use IEEE.MATH_REAL.all; package io_types is --- STANDARD TYPES --- - type ext_protocol_impl_t is record - payload, control: STD_LOGIC_VECTOR; - end record ext_protocol_impl_t; - - type int_protocol_impl_t is record - payload : STD_LOGIC_VECTOR; - -- ADD MORE STUFF WHEN WE HAVE DECIDED UPON DRIVER INTERFACE - end record int_protocol_impl_t; - type ext_protocol_def_t is record name: string (1 to 20); payload_width: natural; @@ -22,46 +13,46 @@ package io_types is type interface_inst_t is record socbridge: ext_protocol_def_t; - spi: ext_protocol_def_t; end record interface_inst_t; --- PROTOCOL INFORMATION --- constant interface_inst : interface_inst_t := ( - ("SoCBridge ", 8, 2, 2), - ("SPI ", 1, 3, 3) + socbridge => ("SoCBridge ", 8, 2, 2) ); --- AUTOGENERATED TYPES --- + type ext_socbridge_in_t is record + payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); + control : STD_LOGIC_VECTOR(interface_inst.socbridge.control_width_in - 1 downto 0); + end record ext_socbridge_in_t; + + type ext_socbridge_out_t is record + payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); + control : STD_LOGIC_VECTOR(interface_inst.socbridge.control_width_in - 1 downto 0); + end record ext_socbridge_out_t; + + type int_socbridge_in_t is record + payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); + end record int_socbridge_in_t; + + type int_socbridge_out_t is record + payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); + end record int_socbridge_out_t; + type ext_interface_in_t is record - socbridge : ext_protocol_impl_t( - payload(interface_inst.socbridge.payload_width - 1 downto 0), - control(interface_inst.socbridge.control_width_in - 1 downto 0)); - spi : ext_protocol_impl_t( - payload(interface_inst.spi.payload_width - 1 downto 0), - control(interface_inst.spi.control_width_in - 1 downto 0)); + socbridge : ext_socbridge_in_t; end record ext_interface_in_t; type ext_interface_out_t is record - socbridge : ext_protocol_impl_t( - payload(interface_inst.socbridge.payload_width - 1 downto 0), - control(interface_inst.socbridge.control_width_out - 1 downto 0)); - spi : ext_protocol_impl_t( - payload(interface_inst.spi.payload_width - 1 downto 0), - control(interface_inst.spi.control_width_out - 1 downto 0)); + socbridge : ext_socbridge_out_t; end record ext_interface_out_t; type int_interface_in_t is record - socbridge : int_protocol_impl_t( - payload(interface_inst.socbridge.payload_width - 1 downto 0)); - spi : int_protocol_impl_t( - payload(interface_inst.spi.payload_width - 1 downto 0)); + socbridge : int_socbridge_in_t; end record int_interface_in_t; type int_interface_out_t is record - socbridge : int_protocol_impl_t( - payload(interface_inst.socbridge.payload_width - 1 downto 0)); - spi : int_protocol_impl_t( - payload(interface_inst.spi.payload_width - 1 downto 0)); + socbridge : int_socbridge_out_t; end record int_interface_out_t; end package io_types; From 0c3612954090038fbbb1c345e74f63e2ba2fe190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Thu, 20 Feb 2025 10:08:51 +0100 Subject: [PATCH 02/40] added more template stuff to ganimede --- src/ganimede.vhd | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/ganimede.vhd b/src/ganimede.vhd index 33eb20d..9521259 100644 --- a/src/ganimede.vhd +++ b/src/ganimede.vhd @@ -5,18 +5,26 @@ use work.io_types.all; entity ganimede is port ( + clk : in std_logic; + reset : in std_logic; ext_interface_in : in ext_interface_in_t; - ext_interface_out : out ext_interface_out_t + ext_interface_out : out ext_interface_out_t; + int_interface_in : in int_interface_in_t; + int_interface_out : out int_interface_out_t ); end entity ganimede; architecture rtl of ganimede is --- SIGNALS INTERFACING THE IP CORE - signal int_interface_in : int_interface_in_t; - signal int_interface_out : int_interface_out_t; + signal gan_int_interface_in : int_interface_in_t; + signal gan_int_interface_out : int_interface_out_t; + signal gan_ext_interface_in : ext_interface_in_t; + signal gan_ext_interface_out : ext_interface_out_t; --- COMPONENT DECLERATIONS --- component socbridge_driver is port( + clk : in std_logic; + reset : in std_logic; ext_in : in ext_socbridge_in_t; ext_out : out ext_socbridge_out_t; int_in : in int_socbridge_in_t; @@ -25,8 +33,29 @@ architecture rtl of ganimede is end component; begin + --- CONNECT EXTERNAL SIGNALS TO INTERNAL CONNECTIONS --- + gan_int_interface_in <= int_interface_in; + int_interface_out <= gan_int_interface_out; + gan_ext_interface_in <= ext_interface_in; + ext_interface_out <= gan_ext_interface_out; + --- DRIVER INSTANTIATION --- + socbridge_driver_inst: socbridge_driver + port map( + clk => clk, + reset => reset, + ext_in => gan_ext_interface_in.socbridge, + ext_out => gan_ext_interface_out.socbridge, + int_in => gan_int_interface_in.socbridge, + int_out => gan_int_interface_out.socbridge + ); - + + + --- FIFO - DRIVER CONNECTION --- + + + --- FIFO - IP-CORE CONNECTION --- + end architecture rtl; From c6d138b31fb59705e0d23a070acc1b92cff0b088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Thu, 20 Feb 2025 14:23:14 +0100 Subject: [PATCH 03/40] fixed typing issue for driver definition and added fifo control signals to interface record --- src/ganimede.vhd | 31 ++++++++++++++++++++++--------- src/io_type_pkg.vhd | 2 ++ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/ganimede.vhd b/src/ganimede.vhd index 9521259..e95d003 100644 --- a/src/ganimede.vhd +++ b/src/ganimede.vhd @@ -14,21 +14,39 @@ entity ganimede is ); end entity ganimede; architecture rtl of ganimede is - --- SIGNALS INTERFACING THE IP CORE + --- SIGNAL DECLERATIONS --- signal gan_int_interface_in : int_interface_in_t; signal gan_int_interface_out : int_interface_out_t; signal gan_ext_interface_in : ext_interface_in_t; signal gan_ext_interface_out : ext_interface_out_t; + + --signal gan_socbridge_WE_in : std_logic; + --signal gan_socbridge_WE_out : std_logic; + --signal gan_socbridge_is_full_in : std_logic; + --signal gan_socbridge_is_full_out : std_logic; --- COMPONENT DECLERATIONS --- + --component fifo is + -- generic( + -- WIDTH : positive; + -- DEPTH : positive + -- ); + -- port( + -- clk, reset, read_enable, write_enable : in std_logic; + -- is_full, is_empty : out std_logic; + -- data_in : in std_logic_vector(WIDTH - 1 downto 0); + -- data_out : out std_logic_vector(WIDTH - 1 downto 0) + -- ); + --end component; + component socbridge_driver is port( clk : in std_logic; reset : in std_logic; ext_in : in ext_socbridge_in_t; ext_out : out ext_socbridge_out_t; - int_in : in int_socbridge_in_t; - int_out : out int_socbridge_out_t + int_in : out int_socbridge_in_t; + int_out : in int_socbridge_out_t ); end component; @@ -50,12 +68,7 @@ begin int_out => gan_int_interface_out.socbridge ); + --- LATER WE ADD OPTIMIZATIONS HERE --- - - --- FIFO - DRIVER CONNECTION --- - - - --- FIFO - IP-CORE CONNECTION --- - end architecture rtl; diff --git a/src/io_type_pkg.vhd b/src/io_type_pkg.vhd index 48fda5e..3afb8f0 100644 --- a/src/io_type_pkg.vhd +++ b/src/io_type_pkg.vhd @@ -33,10 +33,12 @@ package io_types is type int_socbridge_in_t is record payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); + write_enable_in, is_full_out : std_logic; end record int_socbridge_in_t; type int_socbridge_out_t is record payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); + write_enable_out, is_full_in : std_logic; end record int_socbridge_out_t; type ext_interface_in_t is record From f8cba470374964df93e14225d2f041c45983ed80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Tue, 25 Feb 2025 13:53:21 +0100 Subject: [PATCH 04/40] added topology --- topology.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 topology.md diff --git a/topology.md b/topology.md new file mode 100644 index 0000000..dc0b2a9 --- /dev/null +++ b/topology.md @@ -0,0 +1,32 @@ + + +------------------------------------------------------+ +--------------- + | | | + | +-----------------+ | | + *From host* | | Instruction | G A N I M E D E | | + --------------------------->| queue + | | | IP-CORE + | | scheduler | | | + | +-----------------+ | | + | *DMA control*| | | + | | | | + +--------+ | +--------+ | +-----------------+ | | + | Inter- | data + | | Driver |<---+ | Per interface | | data + | + | face 1 |<=================>| 1 |<===|===>| optimizations |<=============================>| + | | control | | | | | (generic) | | control | + +--------+ | +--------+ | +-----------------+ | | + | | | | + +--------+ | +--------+ | +-----------------+ | | + | Inter- | data + | | Driver |<---+ | Per interface | | data + | + | face 2 |<=================>| 2 |<===|===>| optimizations |<=============================>| + | | control | | | | | (generic) | | control | + +--------+ | +--------+ | +-----------------+ | | + ... ... ... ... ... ... ... ... ... ...|... . ... ... . ... ...... . ... ... . ... . | + +--------+ | +--------+ | +-----------------+ | | + | Inter- | data + | | Driver |<---+ | Per interface | | data + | + | face n |<=================>| n |<=======>| optimizations |<=============================>| + | | control | | | | (generic) | | control | + +--------+ | +--------+ +-----------------+ | | + | | | + +------------------------------------------------------+ +--------------- + + +This wont be the first version, but the finished version might look something like this. From e87c54d4ef0a57572fe5609ad01dfc4b7ed4cea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Thu, 20 Feb 2025 14:24:58 +0100 Subject: [PATCH 05/40] added initial driver file --- src/socbridge_driver.vhd | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/socbridge_driver.vhd diff --git a/src/socbridge_driver.vhd b/src/socbridge_driver.vhd new file mode 100644 index 0000000..160db9e --- /dev/null +++ b/src/socbridge_driver.vhd @@ -0,0 +1,24 @@ +library IEEE; +use IEEE.std_logic_1164.all; +library work; +use work.io_types.all; + + +entity socbridge_driver is + port( + clk : in std_logic; + reset : in std_logic; + ext_in : in ext_socbridge_in_t; + ext_out : out ext_socbridge_out_t; + int_in : out int_socbridge_in_t; + int_out : in int_socbridge_out_t + ); +end entity socbridge_driver; + +architecture rtl of socbridge_driver is + + +begin + ext_out <= (payload => (others => '0'), control => (others => '0')); + int_in <= (payload => (others => '0'), write_enable_in => '0', is_full_out =>'0'); +end architecture rtl; From cde67ccba112dc1debd34499adb7d030cfb73043 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Thu, 20 Feb 2025 16:23:00 +0100 Subject: [PATCH 06/40] inital work on the example socbridge driver --- src/socbridge_driver.vhd | 57 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/src/socbridge_driver.vhd b/src/socbridge_driver.vhd index 160db9e..2334bb3 100644 --- a/src/socbridge_driver.vhd +++ b/src/socbridge_driver.vhd @@ -7,7 +7,7 @@ use work.io_types.all; entity socbridge_driver is port( clk : in std_logic; - reset : in std_logic; + rst : in std_logic; ext_in : in ext_socbridge_in_t; ext_out : out ext_socbridge_out_t; int_in : out int_socbridge_in_t; @@ -17,8 +17,59 @@ end entity socbridge_driver; architecture rtl of socbridge_driver is + signal ext_d_in, ext_d_out,ext_d_in_reg, ext_d_out_reg : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); + signal ext_clk_in, ext_clk_out, ext_parity_in, ext_parity_out : std_logic; + + + type command_t is + (IDLE, WRITE_ADD, WRITE, READ_ADD, READ, P_ERR); + + type response_t is + (WRITE_ACK, READ_RESPONSE, UNKNOWN); + + type state_t is + (RESET, IDLE, TX_HEADER, TX_BODY, TX_ACK, RX_HEADER, RX_RESPONSE, RX_BODY); + + signal curr_state, next_state : state_t; + signal curr_command : command_t; + signal curr_command_bits : std_logic_vector(4 downto 0); + signal curr_respoonse : response_t; begin - ext_out <= (payload => (others => '0'), control => (others => '0')); - int_in <= (payload => (others => '0'), write_enable_in => '0', is_full_out =>'0'); + ext_out.payload <= ext_d_out_reg; + ext_out.control <= ext_clk_out & ext_parity_out; + ext_d_in <= ext_in.payload; + ext_parity_in <= ext_out.control(0); + ext_clk_in <= ext_out.control(1); + + -- Create combinational bindings for command/response types + with curr_command select + curr_command_bits <= "00000" when IDLE, + "10000" when WRITE_ADD, + "10100" when WRITE, + "11000" when READ_ADD, + "11100" when READ, + "01001" when P_ERR, + "11111" when others; + with ext_d_in(7 downto 3) select + curr_respoonse <= WRITE_ACK when "00001" or "00101", + READ_RESPONSE when "01000" or "01100", + UNKNOWN when others; + + + -- Process updating internal registers based on primary clock + reg_proc: process(ext_clk_in, rst) + begin + if(rst = '1') then + ext_clk_out <= '0'; + ext_d_in_reg <= (others => '0'); + + elsif(rising_edge(ext_clk_in)) then + ext_clk_out <= not ext_clk_out; + ext_d_in_reg <= ext_d_in; + end if; + end process reg_proc; + + + end architecture rtl; From 12897f0ae2b5d87eee14a0cc452371efbe9c8bc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Mon, 24 Feb 2025 17:11:25 +0100 Subject: [PATCH 07/40] made socbridge driver testbench and continued development on the driver --- src/socbridge_driver.vhd | 94 ++++++++++++++++++------- src/socbridge_driver_tb.vhd | 137 ++++++++++++++++++++++++++++++++++++ 2 files changed, 204 insertions(+), 27 deletions(-) create mode 100644 src/socbridge_driver_tb.vhd diff --git a/src/socbridge_driver.vhd b/src/socbridge_driver.vhd index 2334bb3..b4888fa 100644 --- a/src/socbridge_driver.vhd +++ b/src/socbridge_driver.vhd @@ -16,16 +16,27 @@ entity socbridge_driver is end entity socbridge_driver; architecture rtl of socbridge_driver is + pure function calc_parity( + d : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0) + ) return std_logic is + variable parity : std_logic; + begin + parity := d(0); + for x in 1 to d'length - 1 loop + parity := parity xor d(x); + end loop; + return not parity; + end function; signal ext_d_in, ext_d_out,ext_d_in_reg, ext_d_out_reg : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); - signal ext_clk_in, ext_clk_out, ext_parity_in, ext_parity_out : std_logic; + signal ext_clk_in, ext_clk_out, ext_parity_in, ext_parity_out, ext_next_parity_out : std_logic; type command_t is - (IDLE, WRITE_ADD, WRITE, READ_ADD, READ, P_ERR); + (NO_OP, WRITE_ADD, WRITE, READ_ADD, READ, P_ERR); type response_t is - (WRITE_ACK, READ_RESPONSE, UNKNOWN); + (NO_OP, WRITE_ACK, READ_RESPONSE); type state_t is (RESET, IDLE, TX_HEADER, TX_BODY, TX_ACK, RX_HEADER, RX_RESPONSE, RX_BODY); @@ -34,41 +45,70 @@ architecture rtl of socbridge_driver is signal curr_command : command_t; signal curr_command_bits : std_logic_vector(4 downto 0); signal curr_respoonse : response_t; - + signal curr_response_bits : std_logic_vector(4 downto 0); begin - ext_out.payload <= ext_d_out_reg; - ext_out.control <= ext_clk_out & ext_parity_out; - ext_d_in <= ext_in.payload; - ext_parity_in <= ext_out.control(0); - ext_clk_in <= ext_out.control(1); + comb_proc: process(ext_in, int_out, ext_d_out_reg, ext_clk_out, ext_parity_out, curr_state) + begin + ext_next_parity_out <= calc_parity(int_out.payload); + ext_out.payload <= ext_d_out_reg; + ext_out.control <= ext_clk_out & ext_parity_out; + ext_d_in <= ext_in.payload; + ext_parity_in <= ext_in.control(0); + ext_clk_in <= ext_in.control(1); + curr_response_bits <= ext_d_in(7 downto 3); + -- Create combinational bindings for command/response types + with curr_command select + curr_command_bits <= "00000" when NO_OP, + "10000" when WRITE_ADD, + "10100" when WRITE, + "11000" when READ_ADD, + "11100" when READ, + "01001" when P_ERR, + "11111" when others; + with curr_response_bits select + curr_respoonse <= WRITE_ACK when "00001", + WRITE_ACK when "00101", + READ_RESPONSE when "01000", + READ_RESPONSE when "01100", + NO_OP when others; + + case curr_state is + when IDLE => + if curr_command = WRITE or curr_command = WRITE_ADD then + next_state <= TX_HEADER; + elsif curr_command = READ or curr_command = READ_ADD then + next_state <= RX_HEADER; + else + next_state <= IDLE; + end if; + when RESET => + when TX_HEADER => + when TX_BODY => + when TX_ACK => + when RX_HEADER => + when RX_RESPONSE => + when RX_BODY => + end case; - -- Create combinational bindings for command/response types - with curr_command select - curr_command_bits <= "00000" when IDLE, - "10000" when WRITE_ADD, - "10100" when WRITE, - "11000" when READ_ADD, - "11100" when READ, - "01001" when P_ERR, - "11111" when others; - with ext_d_in(7 downto 3) select - curr_respoonse <= WRITE_ACK when "00001" or "00101", - READ_RESPONSE when "01000" or "01100", - UNKNOWN when others; - - + end process comb_proc; -- Process updating internal registers based on primary clock - reg_proc: process(ext_clk_in, rst) + seq_proc: process(ext_clk_in, rst) begin if(rst = '1') then - ext_clk_out <= '0'; ext_d_in_reg <= (others => '0'); + ext_d_out_reg <= (others => '0'); + ext_clk_out <= '0'; + ext_parity_out <= '1'; + curr_state <= IDLE; elsif(rising_edge(ext_clk_in)) then ext_clk_out <= not ext_clk_out; ext_d_in_reg <= ext_d_in; + ext_d_out_reg <= int_out.payload; + ext_parity_out <= ext_next_parity_out; + curr_state <= next_state; end if; - end process reg_proc; + end process seq_proc; diff --git a/src/socbridge_driver_tb.vhd b/src/socbridge_driver_tb.vhd new file mode 100644 index 0000000..239400d --- /dev/null +++ b/src/socbridge_driver_tb.vhd @@ -0,0 +1,137 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.MATH_REAL.all; +library work; +use work.io_types.all; + + +entity socbridge_driver_tb is +end entity socbridge_driver_tb; + +architecture tb of socbridge_driver_tb is + pure function calc_parity( + d : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0) + ) return std_logic is + variable parity : std_logic; + begin + parity := d(0); + for x in 1 to d'length - 1 loop + parity := parity xor d(x); + end loop; + return not parity; + end function; + + + component socbridge_driver is + port( + clk : in std_logic; + rst : in std_logic; + ext_in : in ext_socbridge_in_t; + ext_out : out ext_socbridge_out_t; + int_in : out int_socbridge_in_t; + int_out : in int_socbridge_out_t + ); + end component socbridge_driver; + signal clk : std_logic := '0'; + signal rst : std_logic := '0'; + signal ext_in : ext_socbridge_in_t; + signal ext_out : ext_socbridge_out_t; + signal int_in : int_socbridge_in_t; + signal int_out : int_socbridge_out_t; + + signal curr_word : std_logic_vector(ext_in.payload'length - 1 downto 0); + + constant CLK_PERIOD : TIME := 10 ns; + constant SIMULATION_CYCLE_COUNT : INTEGER := 100; + +begin + + + socbridge_driver_inst: entity work.socbridge_driver + port map( + clk => clk, + rst => rst, + ext_in => ext_in, + ext_out => ext_out, + int_in => int_in, + int_out => int_out + ); + + real_clk_proc: process + begin + clk <= '0'; + for x in 0 to SIMULATION_CYCLE_COUNT*2 loop + clk <= not clk; + ext_in.control(1) <= clk; + wait for CLK_PERIOD / 2; + end loop; + wait; + end process real_clk_proc; + + + verify_clk: process + variable last_clk : std_logic; + begin + wait for CLK_PERIOD / 2; + for x in 0 to SIMULATION_CYCLE_COUNT loop + if last_clk = ext_out.control(1) then + report "Secondary side clk not correct." severity warning; + end if; + last_clk := ext_out.control(1); + wait for CLK_PERIOD; + end loop; + wait; + end process verify_clk; + + verify_parity: process + variable curr_parity : std_logic; + begin + for x in 0 to SIMULATION_CYCLE_COUNT * 2 loop + curr_parity := calc_parity(ext_out.payload); + if not (curr_parity = ext_out.control(0)) then + report "Secondary side parity not correct" severity warning; + end if; + wait for CLK_PERIOD / 2; + end loop; + wait; + end process verify_parity; + + external_stimulus_signal: process(curr_word) + begin + ext_in.payload <= curr_word; + ext_in.control(0) <= calc_parity(curr_word); + end process external_stimulus_signal; + + external_stimulus: process + begin + rst <= '1'; + wait for 3 * CLK_PERIOD; + rst <= '0'; + curr_word <= "00000000"; + wait for CLK_PERIOD*10; + wait; + end process external_stimulus; + + + internal_stimulus: process + begin + wait for 3 * CLK_PERIOD; + wait for CLK_PERIOD / 2; + int_out.payload <= "00000000"; + wait for CLK_PERIOD; + int_out.payload <= "00000001"; + wait for CLK_PERIOD; + int_out.payload <= "00000011"; + wait for CLK_PERIOD; + int_out.payload <= "00000111"; + wait for CLK_PERIOD; + int_out.payload <= "00001111"; + wait for CLK_PERIOD; + int_out.payload <= "00011111"; + wait for CLK_PERIOD; + int_out.payload <= "00111111"; + wait for CLK_PERIOD; + wait; + end process internal_stimulus; + +end architecture tb ; From 147d9e4d7bcd8e4a1f7aede0236a4f0052da0992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Tue, 25 Feb 2025 14:26:11 +0100 Subject: [PATCH 08/40] added next_state concurrent assignment --- src/socbridge_driver.vhd | 50 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/socbridge_driver.vhd b/src/socbridge_driver.vhd index b4888fa..e9fcb6a 100644 --- a/src/socbridge_driver.vhd +++ b/src/socbridge_driver.vhd @@ -72,6 +72,31 @@ begin READ_RESPONSE when "01100", NO_OP when others; + --- State Transition Diagram --- +-- +-- +-----+ +-- \|/ | +-- RESET --+ +-- | +-- | +-- IDLE<-------------------+ +-- / \ | +-- / \ | +-- / \ | +-- \|/ \|/ | +-- TX_HEADER RX_HEADER | +-- | | | +-- | | ----+ | +-- \|/ \|/ \|/ | | +-- TX_BODY RX_RESPONSE---+ | +-- | | | +-- | +--+ | | +-- \|/\|/ | \|/ | +-- TX_ACK--+ RX_BODY | +-- | | | +-- | | | +-- +-----------+--------------+ +-- case curr_state is when IDLE => if curr_command = WRITE or curr_command = WRITE_ADD then @@ -82,12 +107,37 @@ begin next_state <= IDLE; end if; when RESET => + next_state <= IDLE; when TX_HEADER => + -- The header only takes one word (cycle) to transmit. + -- Continue to body directly afterwards. + next_state <= TX_BODY; when TX_BODY => + -- Here we want to stay in TX_BODY for the duration of a packet. + -- Right now, we transfer one single word at a time for simplicity + next_state <= TX_ACK; when TX_ACK => + -- Wait for write acknowledgement. + if curr_respoonse = WRITE_ACK then + next_state <= IDLE; + else + next_state <= TX_ACK; + end if; when RX_HEADER => + -- The header only takes one word (cycle) to transmit. + -- Continue to awaiting response directly afterwards. + next_state <= RX_RESPONSE; when RX_RESPONSE => + -- Wait for read response. + if curr_respoonse = READ_RESPONSE then + next_state <= RX_BODY; + else + next_state <= RX_RESPONSE; + end if; when RX_BODY => + -- Here we want to stay in RX_BODY for the duration of a packet. + -- Right now, we receive only one single word at a time for simplicity + next_state <= IDLE; end case; end process comb_proc; From 52b3b6a7cabcd12a0a6cf243f77a96d39efd0305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Tue, 25 Feb 2025 16:17:34 +0100 Subject: [PATCH 09/40] cleaned up the code in accordance with the two process method --- src/socbridge_driver.vhd | 101 ++++++++++++++++++++++++++------------- 1 file changed, 69 insertions(+), 32 deletions(-) diff --git a/src/socbridge_driver.vhd b/src/socbridge_driver.vhd index e9fcb6a..c92981c 100644 --- a/src/socbridge_driver.vhd +++ b/src/socbridge_driver.vhd @@ -16,6 +16,26 @@ entity socbridge_driver is end entity socbridge_driver; architecture rtl of socbridge_driver is + type command_t is + (NO_OP, WRITE_ADD, WRITE, READ_ADD, READ, P_ERR); + + type response_t is + (NO_OP, WRITE_ACK, READ_RESPONSE); + + type state_t is + (RESET, IDLE, TX_HEADER, TX_BODY, TX_ACK, RX_HEADER, RX_RESPONSE, RX_BODY); + + type ext_protocol_t is record + data : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); + clk : std_logic; + parity : std_logic; + end record ext_protocol_t; + + type state_rec_t is record + curr_state: state_t; + ext_in_reg, ext_out_reg : ext_protocol_t; + end record state_rec_t; + pure function calc_parity( d : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0) ) return std_logic is @@ -28,34 +48,48 @@ architecture rtl of socbridge_driver is return not parity; end function; - signal ext_d_in, ext_d_out,ext_d_in_reg, ext_d_out_reg : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); - signal ext_clk_in, ext_clk_out, ext_parity_in, ext_parity_out, ext_next_parity_out : std_logic; + pure function create_ext_protocol_from_io_type_in( + input : ext_socbridge_in_t + ) return ext_protocol_t is + variable val : ext_protocol_t; + begin + val.data := input.payload; + val.clk := input.control(1); + val.parity := input.control(0); + return val; + end function; + pure function create_io_type_out_from_ext_protocol( + input : ext_protocol_t + ) return ext_socbridge_out_t is + variable val : ext_socbridge_out_t; + begin + val.payload:= input.data; + val.control(1) := input.clk; + val.control(0) := input.parity; + return val; + end function; + + signal next_parity_out : std_logic; - type command_t is - (NO_OP, WRITE_ADD, WRITE, READ_ADD, READ, P_ERR); - type response_t is - (NO_OP, WRITE_ACK, READ_RESPONSE); - - type state_t is - (RESET, IDLE, TX_HEADER, TX_BODY, TX_ACK, RX_HEADER, RX_RESPONSE, RX_BODY); - - signal curr_state, next_state : state_t; + signal ext_in_rec : ext_protocol_t; + signal ext_out_rec : ext_protocol_t; + signal next_state : state_t; signal curr_command : command_t; signal curr_command_bits : std_logic_vector(4 downto 0); signal curr_respoonse : response_t; signal curr_response_bits : std_logic_vector(4 downto 0); + signal st : state_rec_t; begin - comb_proc: process(ext_in, int_out, ext_d_out_reg, ext_clk_out, ext_parity_out, curr_state) + comb_proc: process(ext_in, int_out, st) begin - ext_next_parity_out <= calc_parity(int_out.payload); - ext_out.payload <= ext_d_out_reg; - ext_out.control <= ext_clk_out & ext_parity_out; - ext_d_in <= ext_in.payload; - ext_parity_in <= ext_in.control(0); - ext_clk_in <= ext_in.control(1); - curr_response_bits <= ext_d_in(7 downto 3); + ext_in_rec <= create_ext_protocol_from_io_type_in(ext_in); + ext_out <= create_io_type_out_from_ext_protocol(ext_out_rec); + next_parity_out <= calc_parity(int_out.payload); + ext_out.payload <= st.ext_out_reg.data; + ext_out.control <= st.ext_out_reg.clk & st.ext_out_reg.parity; + curr_response_bits <= ext_in_rec.data(7 downto 3); -- Create combinational bindings for command/response types with curr_command select curr_command_bits <= "00000" when NO_OP, @@ -97,7 +131,8 @@ begin -- | | | -- +-----------+--------------+ -- - case curr_state is +--- Next State Assignment --- + case st.curr_state is when IDLE => if curr_command = WRITE or curr_command = WRITE_ADD then next_state <= TX_HEADER; @@ -142,21 +177,23 @@ begin end process comb_proc; -- Process updating internal registers based on primary clock - seq_proc: process(ext_clk_in, rst) + seq_proc: process(ext_in_rec.clk, rst) begin if(rst = '1') then - ext_d_in_reg <= (others => '0'); - ext_d_out_reg <= (others => '0'); - ext_clk_out <= '0'; - ext_parity_out <= '1'; - curr_state <= IDLE; + st.ext_in_reg.data <= (others => '0'); + st.ext_out_reg.data <= (others => '0'); + st.ext_out_reg.clk <= '0'; + st.ext_out_reg.parity <= '1'; + st.curr_state <= IDLE; - elsif(rising_edge(ext_clk_in)) then - ext_clk_out <= not ext_clk_out; - ext_d_in_reg <= ext_d_in; - ext_d_out_reg <= int_out.payload; - ext_parity_out <= ext_next_parity_out; - curr_state <= next_state; + elsif(rising_edge(ext_in_rec.clk)) then + st.ext_in_reg.data <= ext_in_rec.data; + st.ext_in_reg.clk <= ext_in_rec.clk; + st.ext_in_reg.parity <= ext_in_rec.parity; + st.ext_out_reg.data <= int_out.payload; + st.ext_out_reg.clk <= not st.ext_out_reg.clk; + st.ext_out_reg.parity <= next_parity_out; + st.curr_state <= next_state; end if; end process seq_proc; From d7638c64cd2909c37001982f02da14ac857862ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Tue, 25 Feb 2025 17:08:20 +0100 Subject: [PATCH 10/40] begun work on output logic based on state --- src/socbridge_driver.vhd | 38 +++++++++++++++++++++++++++++-------- src/socbridge_driver_tb.vhd | 38 +++++++++++++++++++------------------ 2 files changed, 50 insertions(+), 26 deletions(-) diff --git a/src/socbridge_driver.vhd b/src/socbridge_driver.vhd index c92981c..f0b9b77 100644 --- a/src/socbridge_driver.vhd +++ b/src/socbridge_driver.vhd @@ -74,7 +74,7 @@ architecture rtl of socbridge_driver is signal ext_in_rec : ext_protocol_t; - signal ext_out_rec : ext_protocol_t; + signal ext_out_data_cmd : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); signal next_state : state_t; signal curr_command : command_t; signal curr_command_bits : std_logic_vector(4 downto 0); @@ -84,13 +84,14 @@ architecture rtl of socbridge_driver is begin comb_proc: process(ext_in, int_out, st) begin + -- Outputs + ext_out <= create_io_type_out_from_ext_protocol(st.ext_out_reg); + int_in.payload <= st.ext_in_reg.data; + + -- Helpful Bindings -- ext_in_rec <= create_ext_protocol_from_io_type_in(ext_in); - ext_out <= create_io_type_out_from_ext_protocol(ext_out_rec); - next_parity_out <= calc_parity(int_out.payload); - ext_out.payload <= st.ext_out_reg.data; - ext_out.control <= st.ext_out_reg.clk & st.ext_out_reg.parity; curr_response_bits <= ext_in_rec.data(7 downto 3); - -- Create combinational bindings for command/response types + next_parity_out <= calc_parity(ext_out_data_cmd); with curr_command select curr_command_bits <= "00000" when NO_OP, "10000" when WRITE_ADD, @@ -131,7 +132,7 @@ begin -- | | | -- +-----------+--------------+ -- ---- Next State Assignment --- + --- Next State Assignment --- case st.curr_state is when IDLE => if curr_command = WRITE or curr_command = WRITE_ADD then @@ -174,7 +175,28 @@ begin -- Right now, we receive only one single word at a time for simplicity next_state <= IDLE; end case; - + + --- Combinatorial output based on current state --- + ext_out_data_cmd <= (others => '0'); + int_in.is_full_out <= '1'; + int_in.write_enable_in <= '0'; + case st.curr_state is + when IDLE => + when RESET => + when TX_HEADER => + curr_command <= WRITE; + ext_out_data_cmd <= curr_command_bits & "001"; + when TX_BODY => + ext_out_data_cmd <= int_out.payload; + int_in.is_full_out <= '0'; + when TX_ACK => + when RX_HEADER => + curr_command <= READ; + ext_out_data_cmd <= curr_command_bits & "001"; + when RX_RESPONSE => + when RX_BODY => + end case; + end process comb_proc; -- Process updating internal registers based on primary clock seq_proc: process(ext_in_rec.clk, rst) diff --git a/src/socbridge_driver_tb.vhd b/src/socbridge_driver_tb.vhd index 239400d..17dc5d1 100644 --- a/src/socbridge_driver_tb.vhd +++ b/src/socbridge_driver_tb.vhd @@ -33,7 +33,7 @@ architecture tb of socbridge_driver_tb is ); end component socbridge_driver; signal clk : std_logic := '0'; - signal rst : std_logic := '0'; + signal rst : std_logic; signal ext_in : ext_socbridge_in_t; signal ext_out : ext_socbridge_out_t; signal int_in : int_socbridge_in_t; @@ -57,12 +57,11 @@ begin int_out => int_out ); + ext_in.control(1) <= clk; real_clk_proc: process begin - clk <= '0'; for x in 0 to SIMULATION_CYCLE_COUNT*2 loop clk <= not clk; - ext_in.control(1) <= clk; wait for CLK_PERIOD / 2; end loop; wait; @@ -105,9 +104,11 @@ begin external_stimulus: process begin rst <= '1'; + curr_word <= "00000000"; wait for 3 * CLK_PERIOD; rst <= '0'; - curr_word <= "00000000"; + wait for CLK_PERIOD / 2; + -- stimulus goes here wait for CLK_PERIOD*10; wait; end process external_stimulus; @@ -115,22 +116,23 @@ begin internal_stimulus: process begin + int_out.is_full_in <= '0'; + int_out.write_enable_out <= '0'; wait for 3 * CLK_PERIOD; - wait for CLK_PERIOD / 2; + -- stimulus goes here + int_out.write_enable_out <= '1'; int_out.payload <= "00000000"; - wait for CLK_PERIOD; - int_out.payload <= "00000001"; - wait for CLK_PERIOD; - int_out.payload <= "00000011"; - wait for CLK_PERIOD; - int_out.payload <= "00000111"; - wait for CLK_PERIOD; - int_out.payload <= "00001111"; - wait for CLK_PERIOD; - int_out.payload <= "00011111"; - wait for CLK_PERIOD; - int_out.payload <= "00111111"; - wait for CLK_PERIOD; + wait until int_in.is_full_out = '0'; + int_out.payload <= "00000010"; + wait until int_in.is_full_out = '0'; + int_out.payload <= "00000100"; + wait until int_in.is_full_out = '0'; + int_out.payload <= "00001000"; + wait until int_in.is_full_out = '0'; + int_out.payload <= "00010000"; + wait until int_in.is_full_out = '0'; + int_out.payload <= "00100000"; + wait until int_in.is_full_out = '0'; wait; end process internal_stimulus; From 6e3e7deb5eeceebf0a7fa7bb8ccc9f7a8fc68a8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Wed, 26 Feb 2025 17:57:03 +0100 Subject: [PATCH 11/40] At least i know what the problem is... --- src/socbridge_driver.vhd | 100 +++++++++------------------- src/socbridge_driver_tb.vhd | 90 +++++++++++++++++++------ src/socbridge_driver_tb_pkg.vhd | 112 ++++++++++++++++++++++++++++++++ 3 files changed, 212 insertions(+), 90 deletions(-) create mode 100644 src/socbridge_driver_tb_pkg.vhd diff --git a/src/socbridge_driver.vhd b/src/socbridge_driver.vhd index f0b9b77..3102ecf 100644 --- a/src/socbridge_driver.vhd +++ b/src/socbridge_driver.vhd @@ -1,13 +1,16 @@ library IEEE; use IEEE.std_logic_1164.all; +use IEEE.NUMERIC_STD.all; library work; use work.io_types.all; +use work.socbridge_driver_tb_pkg.all; entity socbridge_driver is port( clk : in std_logic; - rst : in std_logic; + rst : in std_logic; + cmd : in command_t; ext_in : in ext_socbridge_in_t; ext_out : out ext_socbridge_out_t; int_in : out int_socbridge_in_t; @@ -16,63 +19,8 @@ entity socbridge_driver is end entity socbridge_driver; architecture rtl of socbridge_driver is - type command_t is - (NO_OP, WRITE_ADD, WRITE, READ_ADD, READ, P_ERR); - - type response_t is - (NO_OP, WRITE_ACK, READ_RESPONSE); - - type state_t is - (RESET, IDLE, TX_HEADER, TX_BODY, TX_ACK, RX_HEADER, RX_RESPONSE, RX_BODY); - - type ext_protocol_t is record - data : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); - clk : std_logic; - parity : std_logic; - end record ext_protocol_t; - - type state_rec_t is record - curr_state: state_t; - ext_in_reg, ext_out_reg : ext_protocol_t; - end record state_rec_t; - - pure function calc_parity( - d : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0) - ) return std_logic is - variable parity : std_logic; - begin - parity := d(0); - for x in 1 to d'length - 1 loop - parity := parity xor d(x); - end loop; - return not parity; - end function; - - pure function create_ext_protocol_from_io_type_in( - input : ext_socbridge_in_t - ) return ext_protocol_t is - variable val : ext_protocol_t; - begin - val.data := input.payload; - val.clk := input.control(1); - val.parity := input.control(0); - return val; - end function; - pure function create_io_type_out_from_ext_protocol( - input : ext_protocol_t - ) return ext_socbridge_out_t is - variable val : ext_socbridge_out_t; - begin - val.payload:= input.data; - val.control(1) := input.clk; - val.control(0) := input.parity; - return val; - end function; signal next_parity_out : std_logic; - - - signal ext_in_rec : ext_protocol_t; signal ext_out_data_cmd : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); signal next_state : state_t; @@ -82,6 +30,22 @@ architecture rtl of socbridge_driver is signal curr_response_bits : std_logic_vector(4 downto 0); signal st : state_rec_t; begin + next_parity_out <= calc_parity(ext_out_data_cmd); + --- DEBUG GLOBAL BINDINGS --- + -- synthesis translate_off + G_next_parity_out <= next_parity_out; + G_ext_in_rec <= ext_in_rec; + G_ext_out_data_cmd <= ext_out_data_cmd; + G_next_state <= next_state; + G_curr_command <= curr_command; + G_curr_command_bits <= curr_command_bits; + G_curr_respoonse <= curr_respoonse; + G_curr_response_bits <= curr_response_bits; + G_st <= st; + -- synthesis translate_on + + + comb_proc: process(ext_in, int_out, st) begin -- Outputs @@ -91,15 +55,6 @@ begin -- Helpful Bindings -- ext_in_rec <= create_ext_protocol_from_io_type_in(ext_in); curr_response_bits <= ext_in_rec.data(7 downto 3); - next_parity_out <= calc_parity(ext_out_data_cmd); - with curr_command select - curr_command_bits <= "00000" when NO_OP, - "10000" when WRITE_ADD, - "10100" when WRITE, - "11000" when READ_ADD, - "11100" when READ, - "01001" when P_ERR, - "11111" when others; with curr_response_bits select curr_respoonse <= WRITE_ACK when "00001", WRITE_ACK when "00101", @@ -135,9 +90,9 @@ begin --- Next State Assignment --- case st.curr_state is when IDLE => - if curr_command = WRITE or curr_command = WRITE_ADD then + if cmd = WRITE or cmd = WRITE_ADD then next_state <= TX_HEADER; - elsif curr_command = READ or curr_command = READ_ADD then + elsif cmd = READ or cmd = READ_ADD then next_state <= RX_HEADER; else next_state <= IDLE; @@ -185,7 +140,7 @@ begin when RESET => when TX_HEADER => curr_command <= WRITE; - ext_out_data_cmd <= curr_command_bits & "001"; + ext_out_data_cmd <= get_command_bits(WRITE) & "001"; when TX_BODY => ext_out_data_cmd <= int_out.payload; int_in.is_full_out <= '0'; @@ -196,7 +151,8 @@ begin when RX_RESPONSE => when RX_BODY => end case; - + report "Running comb part with ext_out_data_cmd = " & to_string(ext_out_data_cmd) severity note; + report "Running comb part with next_parity_out = " & std_logic'image(next_parity_out) severity note; end process comb_proc; -- Process updating internal registers based on primary clock seq_proc: process(ext_in_rec.clk, rst) @@ -209,12 +165,14 @@ begin st.curr_state <= IDLE; elsif(rising_edge(ext_in_rec.clk)) then + report "Running seq part with ext_out_data_cmd = " & to_string(ext_out_data_cmd) severity note; + report "Running seq part with next_parity_out = " & std_logic'image(next_parity_out) severity note; + st.ext_out_reg.parity <= next_parity_out; st.ext_in_reg.data <= ext_in_rec.data; st.ext_in_reg.clk <= ext_in_rec.clk; st.ext_in_reg.parity <= ext_in_rec.parity; - st.ext_out_reg.data <= int_out.payload; + st.ext_out_reg.data <= ext_out_data_cmd; st.ext_out_reg.clk <= not st.ext_out_reg.clk; - st.ext_out_reg.parity <= next_parity_out; st.curr_state <= next_state; end if; end process seq_proc; diff --git a/src/socbridge_driver_tb.vhd b/src/socbridge_driver_tb.vhd index 17dc5d1..9b009e1 100644 --- a/src/socbridge_driver_tb.vhd +++ b/src/socbridge_driver_tb.vhd @@ -3,29 +3,31 @@ use IEEE.std_logic_1164.all; use IEEE.MATH_REAL.all; library work; use work.io_types.all; +use work.socbridge_driver_tb_pkg.all; entity socbridge_driver_tb is end entity socbridge_driver_tb; architecture tb of socbridge_driver_tb is - pure function calc_parity( - d : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0) - ) return std_logic is - variable parity : std_logic; + impure function check_next_state(correct_state: state_t) return boolean is begin - parity := d(0); - for x in 1 to d'length - 1 loop - parity := parity xor d(x); - end loop; - return not parity; + if(not (correct_state = G_next_state)) then + report "Next State is not what was expected, found " & state_t'image(G_next_state) + & " but expected " & state_t'image(correct_state) severity error; + return FALSE; + end if; + return TRUE; end function; + + component socbridge_driver is port( clk : in std_logic; - rst : in std_logic; + rst : in std_logic; + cmd : in command_t; ext_in : in ext_socbridge_in_t; ext_out : out ext_socbridge_out_t; int_in : out int_socbridge_in_t; @@ -34,6 +36,7 @@ architecture tb of socbridge_driver_tb is end component socbridge_driver; signal clk : std_logic := '0'; signal rst : std_logic; + signal cmd : command_t; signal ext_in : ext_socbridge_in_t; signal ext_out : ext_socbridge_out_t; signal int_in : int_socbridge_in_t; @@ -45,12 +48,11 @@ architecture tb of socbridge_driver_tb is constant SIMULATION_CYCLE_COUNT : INTEGER := 100; begin - - socbridge_driver_inst: entity work.socbridge_driver port map( clk => clk, rst => rst, + cmd => cmd, ext_in => ext_in, ext_out => ext_out, int_in => int_in, @@ -74,7 +76,7 @@ begin wait for CLK_PERIOD / 2; for x in 0 to SIMULATION_CYCLE_COUNT loop if last_clk = ext_out.control(1) then - report "Secondary side clk not correct." severity warning; + report "Secondary side clk not correct." severity error; end if; last_clk := ext_out.control(1); wait for CLK_PERIOD; @@ -85,16 +87,61 @@ begin verify_parity: process variable curr_parity : std_logic; begin - for x in 0 to SIMULATION_CYCLE_COUNT * 2 loop + for x in 0 to SIMULATION_CYCLE_COUNT * 10 loop curr_parity := calc_parity(ext_out.payload); if not (curr_parity = ext_out.control(0)) then - report "Secondary side parity not correct" severity warning; + report "Secondary side parity not correct" severity error; + wait for CLK_PERIOD; + report "Ending Simulation... " severity FAILURE; end if; - wait for CLK_PERIOD / 2; + wait for CLK_PERIOD / 10; end loop; wait; end process verify_parity; + verify_next_state : process + variable nsv: boolean; + begin + wait for 3 * CLK_PERIOD; + wait for CLK_PERIOD / 2; + nsv := check_next_state(IDLE); + wait for CLK_PERIOD; + nsv := check_next_state(TX_HEADER); + wait for CLK_PERIOD; + nsv := check_next_state(TX_BODY); + wait for CLK_PERIOD; + nsv := check_next_state(TX_ACK); + wait for CLK_PERIOD; + nsv := check_next_state(TX_ACK); + wait for CLK_PERIOD; + nsv := check_next_state(IDLE); + wait for CLK_PERIOD; + nsv := check_next_state(IDLE); + wait for CLK_PERIOD; + nsv := check_next_state(IDLE); + wait for CLK_PERIOD; + nsv := check_next_state(IDLE); + wait for CLK_PERIOD; + nsv := check_next_state(IDLE); + wait for CLK_PERIOD; + nsv := check_next_state(IDLE); + wait for CLK_PERIOD; + nsv := check_next_state(IDLE); + wait for CLK_PERIOD; + wait; + end process verify_next_state; + + command_stimulus: process + begin + cmd <= NO_OP; + wait for 3*CLK_PERIOD; + wait for CLK_PERIOD / 2; + cmd <= WRITE; + wait for CLK_PERIOD; + cmd <= NO_OP; + wait; + end process command_stimulus; + external_stimulus_signal: process(curr_word) begin ext_in.payload <= curr_word; @@ -108,12 +155,11 @@ begin wait for 3 * CLK_PERIOD; rst <= '0'; wait for CLK_PERIOD / 2; - -- stimulus goes here - wait for CLK_PERIOD*10; + wait for 3* CLK_PERIOD; + curr_word <= "00001001"; wait; end process external_stimulus; - internal_stimulus: process begin int_out.is_full_in <= '0'; @@ -123,16 +169,22 @@ begin int_out.write_enable_out <= '1'; int_out.payload <= "00000000"; wait until int_in.is_full_out = '0'; + wait until rising_edge(clk); int_out.payload <= "00000010"; wait until int_in.is_full_out = '0'; + wait until rising_edge(clk); int_out.payload <= "00000100"; wait until int_in.is_full_out = '0'; + wait until rising_edge(clk); int_out.payload <= "00001000"; wait until int_in.is_full_out = '0'; + wait until rising_edge(clk); int_out.payload <= "00010000"; wait until int_in.is_full_out = '0'; + wait until rising_edge(clk); int_out.payload <= "00100000"; wait until int_in.is_full_out = '0'; + wait until rising_edge(clk); wait; end process internal_stimulus; diff --git a/src/socbridge_driver_tb_pkg.vhd b/src/socbridge_driver_tb_pkg.vhd new file mode 100644 index 0000000..676b6ef --- /dev/null +++ b/src/socbridge_driver_tb_pkg.vhd @@ -0,0 +1,112 @@ +library IEEE; +use IEEE.std_logic_1164.all; +library work; +use work.io_types.all; + + +package socbridge_driver_tb_pkg is + type command_t is + (NO_OP, WRITE_ADD, WRITE, READ_ADD, READ, P_ERR); + + type response_t is + (NO_OP, WRITE_ACK, READ_RESPONSE); + + type state_t is + (RESET, IDLE, TX_HEADER, TX_BODY, TX_ACK, RX_HEADER, RX_RESPONSE, RX_BODY); + + type ext_protocol_t is record + data : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); + clk : std_logic; + parity : std_logic; + end record ext_protocol_t; + + type state_rec_t is record + curr_state: state_t; + ext_in_reg, ext_out_reg : ext_protocol_t; + end record state_rec_t; + impure function calc_parity( + d : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0) + ) return std_logic; + pure function create_ext_protocol_from_io_type_in ( + input : ext_socbridge_in_t + ) return ext_protocol_t; + pure function create_io_type_out_from_ext_protocol( + input: ext_protocol_t + ) return ext_socbridge_out_t; + function to_string ( a: std_logic_vector) return string; + pure function get_command_bits(command : command_t) return std_logic_vector; + --- DEBUG GLOBAL SIGNALS --- + -- synthesis translate_off + signal G_next_parity_out : std_logic; + signal G_ext_in_rec : ext_protocol_t; + signal G_ext_out_data_cmd : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); + signal G_next_state : state_t; + signal G_curr_command : command_t; + signal G_curr_command_bits : std_logic_vector(4 downto 0); + signal G_curr_respoonse : response_t; + signal G_curr_response_bits : std_logic_vector(4 downto 0); + signal G_st : state_rec_t; + -- synthesis translate_on + +end package socbridge_driver_tb_pkg; + +package body socbridge_driver_tb_pkg is + function to_string ( a: std_logic_vector) return string is + variable b : string (1 to a'length) := (others => NUL); + variable stri : integer := 1; + begin + for i in a'range loop + b(stri) := std_logic'image(a((i)))(2); + stri := stri+1; + end loop; + return b; + end function; + + impure function calc_parity( + d : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0) + ) return std_logic is + variable parity : std_logic; + begin + parity := d(0); + for x in integer'(1) to d'length - 1 loop + parity := parity xor d(x); + end loop; + return not parity; + end function; + + pure function create_ext_protocol_from_io_type_in( + input : ext_socbridge_in_t + ) return ext_protocol_t is + variable val : ext_protocol_t; + begin + val.data := input.payload; + val.clk := input.control(1); + val.parity := input.control(0); + return val; + end function; + pure function create_io_type_out_from_ext_protocol( + input : ext_protocol_t + ) return ext_socbridge_out_t is + variable val : ext_socbridge_out_t; + begin + val.payload:= input.data; + val.control(1) := input.clk; + val.control(0) := input.parity; + return val; + end function; + pure function get_command_bits(command : command_t) + return std_logic_vector is + variable val : std_logic_vector(4 downto 0); + begin + with command select + val := "00000" when NO_OP, + "10000" when WRITE_ADD, + "10100" when WRITE, + "11000" when READ_ADD, + "11100" when READ, + "01001" when P_ERR, + "11111" when others; + return val; + end function; + +end package body socbridge_driver_tb_pkg; From eb1bb5d328f303e02109b2a0b7474531132fb3db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Thu, 27 Feb 2025 10:55:09 +0100 Subject: [PATCH 12/40] added socbrdige driver tb gtkwave config --- src/socbridge_driver_tb.gtkw | 79 ++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 src/socbridge_driver_tb.gtkw diff --git a/src/socbridge_driver_tb.gtkw b/src/socbridge_driver_tb.gtkw new file mode 100644 index 0000000..3290cb7 --- /dev/null +++ b/src/socbridge_driver_tb.gtkw @@ -0,0 +1,79 @@ +[*] +[*] GTKWave Analyzer v3.3.120 (w)1999-2024 BSI +[*] Wed Feb 26 15:43:46 2025 +[*] +[dumpfile] "/home/kryddan/repos/exjobb-public/src/wave/socbridge_driver_tb-tb.ghw" +[dumpfile_mtime] "Wed Feb 26 15:43:13 2025" +[dumpfile_size] 2378 +[savefile] "/home/kryddan/repos/exjobb-public/src/wave/socbridge_driver_tb.gtkw" +[timestart] 0 +[size] 1920 1080 +[pos] -966 -6 +*-23.724968 40550000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[treeopen] top. +[treeopen] top.socbridge_driver_tb. +[treeopen] top.socbridge_driver_tb_pkg. +[treeopen] top.socbridge_driver_tb_pkg.g_st. +[sst_width] 273 +[signals_width] 214 +[sst_expanded] 1 +[sst_vpaned_height] 324 +@800200 +-Outwards +-Internal +@28 +top.socbridge_driver_tb.int_out.is_full_in +@22 +#{top.socbridge_driver_tb.int_out.payload[7:0]} top.socbridge_driver_tb.int_out.payload[7] top.socbridge_driver_tb.int_out.payload[6] top.socbridge_driver_tb.int_out.payload[5] top.socbridge_driver_tb.int_out.payload[4] top.socbridge_driver_tb.int_out.payload[3] top.socbridge_driver_tb.int_out.payload[2] top.socbridge_driver_tb.int_out.payload[1] top.socbridge_driver_tb.int_out.payload[0] +@28 +top.socbridge_driver_tb.int_out.write_enable_out +@1000200 +-Internal +@800200 +-External +@28 ++{clk} top.socbridge_driver_tb.ext_out.control[1] ++{parity} top.socbridge_driver_tb.ext_out.control[0] ++{next_parity} top.socbridge_driver_tb_pkg.g_next_parity_out +@22 +#{top.socbridge_driver_tb.ext_out.payload[7:0]} top.socbridge_driver_tb.ext_out.payload[7] top.socbridge_driver_tb.ext_out.payload[6] top.socbridge_driver_tb.ext_out.payload[5] top.socbridge_driver_tb.ext_out.payload[4] top.socbridge_driver_tb.ext_out.payload[3] top.socbridge_driver_tb.ext_out.payload[2] top.socbridge_driver_tb.ext_out.payload[1] top.socbridge_driver_tb.ext_out.payload[0] +@1000200 +-External +-Outwards +@800200 +-Inwards +-Internal +@28 +top.socbridge_driver_tb.int_in.is_full_out +@22 +#{top.socbridge_driver_tb.int_in.payload[7:0]} top.socbridge_driver_tb.int_in.payload[7] top.socbridge_driver_tb.int_in.payload[6] top.socbridge_driver_tb.int_in.payload[5] top.socbridge_driver_tb.int_in.payload[4] top.socbridge_driver_tb.int_in.payload[3] top.socbridge_driver_tb.int_in.payload[2] top.socbridge_driver_tb.int_in.payload[1] top.socbridge_driver_tb.int_in.payload[0] +@28 +top.socbridge_driver_tb.int_in.write_enable_in +@1000200 +-Internal +@800200 +-External +@28 ++{clk} top.socbridge_driver_tb.ext_in.control[1] ++{parity} top.socbridge_driver_tb.ext_in.control[0] +@22 +#{top.socbridge_driver_tb.ext_in.payload[7:0]} top.socbridge_driver_tb.ext_in.payload[7] top.socbridge_driver_tb.ext_in.payload[6] top.socbridge_driver_tb.ext_in.payload[5] top.socbridge_driver_tb.ext_in.payload[4] top.socbridge_driver_tb.ext_in.payload[3] top.socbridge_driver_tb.ext_in.payload[2] top.socbridge_driver_tb.ext_in.payload[1] top.socbridge_driver_tb.ext_in.payload[0] +@1000200 +-External +-Inwards +@800200 +-Internal Signals +@420 +top.socbridge_driver_tb_pkg.g_st.curr_state ++{next_state} top.socbridge_driver_tb_pkg.g_next_state +top.socbridge_driver_tb_pkg.g_curr_command +@23 +#{top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[7:0]} top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[7] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[6] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[5] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[4] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[3] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[2] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[1] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[0] +@420 +top.socbridge_driver_tb_pkg.g_curr_respoonse +@1000200 +-Internal Signals +@420 +top.socbridge_driver_tb.cmd +[pattern_trace] 1 +[pattern_trace] 0 From dd7683139c28da554a0361afab6d6466489744f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Thu, 27 Feb 2025 13:48:17 +0100 Subject: [PATCH 13/40] improved testbench and removed unnecessary delay caused by 2PM --- src/socbridge_driver.vhd | 73 ++++++++++++----- src/socbridge_driver_tb.gtkw | 24 +++--- src/socbridge_driver_tb.vhd | 140 +++++++++++++++++++++----------- src/socbridge_driver_tb_pkg.vhd | 15 +--- 4 files changed, 156 insertions(+), 96 deletions(-) diff --git a/src/socbridge_driver.vhd b/src/socbridge_driver.vhd index 3102ecf..d0abb8f 100644 --- a/src/socbridge_driver.vhd +++ b/src/socbridge_driver.vhd @@ -22,29 +22,30 @@ architecture rtl of socbridge_driver is signal next_parity_out : std_logic; signal ext_in_rec : ext_protocol_t; - signal ext_out_data_cmd : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); + shared variable ext_out_data_cmd : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); + signal test : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); signal next_state : state_t; signal curr_command : command_t; signal curr_command_bits : std_logic_vector(4 downto 0); - signal curr_respoonse : response_t; + signal curr_response : response_t; signal curr_response_bits : std_logic_vector(4 downto 0); signal st : state_rec_t; begin - next_parity_out <= calc_parity(ext_out_data_cmd); --- DEBUG GLOBAL BINDINGS --- -- synthesis translate_off G_next_parity_out <= next_parity_out; G_ext_in_rec <= ext_in_rec; - G_ext_out_data_cmd <= ext_out_data_cmd; G_next_state <= next_state; + G_ext_out_data_cmd <=test; G_curr_command <= curr_command; G_curr_command_bits <= curr_command_bits; - G_curr_respoonse <= curr_respoonse; + G_curr_response <= curr_response; G_curr_response_bits <= curr_response_bits; G_st <= st; -- synthesis translate_on - - + ext_in_rec.data <= ext_in.payload; + ext_in_rec.clk <= ext_in.control(1); + ext_in_rec.parity <= ext_in.control(0); comb_proc: process(ext_in, int_out, st) begin @@ -53,10 +54,25 @@ begin int_in.payload <= st.ext_in_reg.data; -- Helpful Bindings -- - ext_in_rec <= create_ext_protocol_from_io_type_in(ext_in); - curr_response_bits <= ext_in_rec.data(7 downto 3); + curr_response_bits <= ext_in.payload(7 downto 3); -- CANT USE EXT_IN_REC here for some reason, the assignment becomes stasteful + -- Not sure that the two process method is helping here: if this was a normal + -- signal assignment there would be no confusion. + -- in the case ... <= ext_in_rec we get + -- curr_resp | ext_in_rec | ext_in + -- 00000 | 00000000 | 00001001 + -- 00000 | 00001001 | 00001001 + -- 00001 | 00001001 | 00001001 + -- 00001 | 00001001 | 00001001 + -- + -- but in the case ... <= ext_in we get + -- curr_resp | ext_in_rec | ext_in + -- 00000 | 00000000 | 00001001 + -- 00001 | 00001001 | 00001001 + -- 00001 | 00001001 | 00001001 + -- 00001 | 00001001 | 00001001 + with curr_response_bits select - curr_respoonse <= WRITE_ACK when "00001", + curr_response <= WRITE_ACK when "00001", WRITE_ACK when "00101", READ_RESPONSE when "01000", READ_RESPONSE when "01100", @@ -109,7 +125,7 @@ begin next_state <= TX_ACK; when TX_ACK => -- Wait for write acknowledgement. - if curr_respoonse = WRITE_ACK then + if curr_response = WRITE_ACK then next_state <= IDLE; else next_state <= TX_ACK; @@ -120,7 +136,7 @@ begin next_state <= RX_RESPONSE; when RX_RESPONSE => -- Wait for read response. - if curr_respoonse = READ_RESPONSE then + if curr_response = READ_RESPONSE then next_state <= RX_BODY; else next_state <= RX_RESPONSE; @@ -132,27 +148,42 @@ begin end case; --- Combinatorial output based on current state --- - ext_out_data_cmd <= (others => '0'); + ext_out_data_cmd := (others => '0'); int_in.is_full_out <= '1'; int_in.write_enable_in <= '0'; case st.curr_state is when IDLE => + if cmd = WRITE or cmd = WRITE_ADD then + ext_out_data_cmd := get_command_bits(WRITE) & "001"; + elsif cmd = READ or cmd = READ_ADD then + ext_out_data_cmd := get_command_bits(READ) & "001"; + end if; when RESET => when TX_HEADER => curr_command <= WRITE; - ext_out_data_cmd <= get_command_bits(WRITE) & "001"; - when TX_BODY => - ext_out_data_cmd <= int_out.payload; + ext_out_data_cmd := int_out.payload; int_in.is_full_out <= '0'; + when TX_BODY => + -- here more logic is needed for mulit word transmission (and address setting) + if cmd = WRITE_ADD then + ext_out_data_cmd := int_out.payload; + int_in.is_full_out <= '0'; + end if; when TX_ACK => when RX_HEADER => curr_command <= READ; - ext_out_data_cmd <= curr_command_bits & "001"; + ext_out_data_cmd := curr_command_bits & "001"; when RX_RESPONSE => when RX_BODY => end case; - report "Running comb part with ext_out_data_cmd = " & to_string(ext_out_data_cmd) severity note; - report "Running comb part with next_parity_out = " & std_logic'image(next_parity_out) severity note; + next_parity_out <= calc_parity(ext_out_data_cmd); + --- DEBUG GLOBAL BINDINGS --- + -- synthesis translate_off + test <= ext_out_data_cmd; + report to_string(ext_out_data_cmd); + report to_string(test); + report to_string(G_ext_out_data_cmd); + -- synthesis translate_on end process comb_proc; -- Process updating internal registers based on primary clock seq_proc: process(ext_in_rec.clk, rst) @@ -165,14 +196,12 @@ begin st.curr_state <= IDLE; elsif(rising_edge(ext_in_rec.clk)) then - report "Running seq part with ext_out_data_cmd = " & to_string(ext_out_data_cmd) severity note; - report "Running seq part with next_parity_out = " & std_logic'image(next_parity_out) severity note; - st.ext_out_reg.parity <= next_parity_out; st.ext_in_reg.data <= ext_in_rec.data; st.ext_in_reg.clk <= ext_in_rec.clk; st.ext_in_reg.parity <= ext_in_rec.parity; st.ext_out_reg.data <= ext_out_data_cmd; st.ext_out_reg.clk <= not st.ext_out_reg.clk; + st.ext_out_reg.parity <= next_parity_out; st.curr_state <= next_state; end if; end process seq_proc; diff --git a/src/socbridge_driver_tb.gtkw b/src/socbridge_driver_tb.gtkw index 3290cb7..4b32853 100644 --- a/src/socbridge_driver_tb.gtkw +++ b/src/socbridge_driver_tb.gtkw @@ -1,15 +1,15 @@ [*] -[*] GTKWave Analyzer v3.3.120 (w)1999-2024 BSI -[*] Wed Feb 26 15:43:46 2025 +[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI +[*] Thu Feb 27 10:27:13 2025 [*] -[dumpfile] "/home/kryddan/repos/exjobb-public/src/wave/socbridge_driver_tb-tb.ghw" -[dumpfile_mtime] "Wed Feb 26 15:43:13 2025" -[dumpfile_size] 2378 -[savefile] "/home/kryddan/repos/exjobb-public/src/wave/socbridge_driver_tb.gtkw" -[timestart] 0 -[size] 1920 1080 -[pos] -966 -6 -*-23.724968 40550000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 +[dumpfile] "/home/thesis1/repos/exjobb-public/src/wave/socbridge_driver_tb-tb.ghw" +[dumpfile_mtime] "Thu Feb 27 10:26:19 2025" +[dumpfile_size] 2417 +[savefile] "/home/thesis1/repos/exjobb-public/src/socbridge_driver_tb.gtkw" +[timestart] 21800000 +[size] 956 1033 +[pos] -1 -1 +*-24.456779 22000000 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 [treeopen] top. [treeopen] top.socbridge_driver_tb. [treeopen] top.socbridge_driver_tb_pkg. @@ -37,6 +37,7 @@ top.socbridge_driver_tb.int_out.write_enable_out +{next_parity} top.socbridge_driver_tb_pkg.g_next_parity_out @22 #{top.socbridge_driver_tb.ext_out.payload[7:0]} top.socbridge_driver_tb.ext_out.payload[7] top.socbridge_driver_tb.ext_out.payload[6] top.socbridge_driver_tb.ext_out.payload[5] top.socbridge_driver_tb.ext_out.payload[4] top.socbridge_driver_tb.ext_out.payload[3] top.socbridge_driver_tb.ext_out.payload[2] top.socbridge_driver_tb.ext_out.payload[1] top.socbridge_driver_tb.ext_out.payload[0] ++{next_payload[7:0]} #{top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[7:0]} top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[7] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[6] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[5] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[4] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[3] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[2] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[1] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[0] @1000200 -External -Outwards @@ -67,9 +68,6 @@ top.socbridge_driver_tb.int_in.write_enable_in top.socbridge_driver_tb_pkg.g_st.curr_state +{next_state} top.socbridge_driver_tb_pkg.g_next_state top.socbridge_driver_tb_pkg.g_curr_command -@23 -#{top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[7:0]} top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[7] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[6] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[5] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[4] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[3] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[2] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[1] top.socbridge_driver_tb_pkg.g_ext_out_data_cmd[0] -@420 top.socbridge_driver_tb_pkg.g_curr_respoonse @1000200 -Internal Signals diff --git a/src/socbridge_driver_tb.vhd b/src/socbridge_driver_tb.vhd index 9b009e1..88d4137 100644 --- a/src/socbridge_driver_tb.vhd +++ b/src/socbridge_driver_tb.vhd @@ -10,18 +10,51 @@ entity socbridge_driver_tb is end entity socbridge_driver_tb; architecture tb of socbridge_driver_tb is - impure function check_next_state(correct_state: state_t) return boolean is + signal clk : std_logic := '0'; + signal rst : std_logic; + signal cmd : command_t; + signal ext_in : ext_socbridge_in_t; + signal ext_out : ext_socbridge_out_t; + signal int_in : int_socbridge_in_t; + signal int_out : int_socbridge_out_t; + signal curr_word : std_logic_vector(ext_in.payload'length - 1 downto 0); + signal expected_out : std_logic_vector(ext_out.payload'length - 1 downto 0); + + constant CLK_PERIOD : TIME := 10 ns; + constant SIMULATION_CYCLE_COUNT : INTEGER := 100; + + procedure fail(error_msg : string) is + begin + wait for CLK_PERIOD; + report "Simulation ending due to: " & error_msg & ". Shutting down..." severity FAILURE; + end procedure; + + procedure check_next_state(correct_state: state_t) is begin if(not (correct_state = G_next_state)) then report "Next State is not what was expected, found " & state_t'image(G_next_state) & " but expected " & state_t'image(correct_state) severity error; - return FALSE; + fail("Next State"); end if; - return TRUE; - end function; - - + end procedure; + + procedure check_data_out(correct_data: std_logic_vector(ext_out.payload'length - 1 downto 0)) is + begin + if(not (correct_data = ext_out.payload)) then + report "Data out is not what was expected, found " & to_string(ext_out.payload) + & " but expected " & to_string(correct_data) severity error; + fail("Data out"); + end if; + end procedure; + procedure check_parity(correct_data: std_logic_vector(ext_out.payload'length - 1 downto 0)) is + begin + if(not (calc_parity(correct_data) = calc_parity(ext_out.payload))) then + report "Parity out is not what was expected, found " & std_logic'image(calc_parity(ext_out.payload)) + & " but expected " & std_logic'image(calc_parity(correct_data)) severity error; + fail("Parity out"); + end if; + end procedure; component socbridge_driver is port( @@ -34,18 +67,6 @@ architecture tb of socbridge_driver_tb is int_out : in int_socbridge_out_t ); end component socbridge_driver; - signal clk : std_logic := '0'; - signal rst : std_logic; - signal cmd : command_t; - signal ext_in : ext_socbridge_in_t; - signal ext_out : ext_socbridge_out_t; - signal int_in : int_socbridge_in_t; - signal int_out : int_socbridge_out_t; - - signal curr_word : std_logic_vector(ext_in.payload'length - 1 downto 0); - - constant CLK_PERIOD : TIME := 10 ns; - constant SIMULATION_CYCLE_COUNT : INTEGER := 100; begin socbridge_driver_inst: entity work.socbridge_driver @@ -68,7 +89,6 @@ begin end loop; wait; end process real_clk_proc; - verify_clk: process variable last_clk : std_logic; @@ -84,52 +104,64 @@ begin wait; end process verify_clk; - verify_parity: process + verify_out_signals: process variable curr_parity : std_logic; begin - for x in 0 to SIMULATION_CYCLE_COUNT * 10 loop - curr_parity := calc_parity(ext_out.payload); - if not (curr_parity = ext_out.control(0)) then - report "Secondary side parity not correct" severity error; - wait for CLK_PERIOD; - report "Ending Simulation... " severity FAILURE; - end if; - wait for CLK_PERIOD / 10; + wait for CLK_PERIOD / 2; + for x in 0 to SIMULATION_CYCLE_COUNT loop + check_data_out(expected_out); + check_parity(expected_out); + wait for CLK_PERIOD; end loop; wait; - end process verify_parity; + end process verify_out_signals; - verify_next_state : process + verify_signals : process variable nsv: boolean; begin + expected_out <= "00000000"; wait for 3 * CLK_PERIOD; - wait for CLK_PERIOD / 2; - nsv := check_next_state(IDLE); + wait for CLK_PERIOD / 3; + expected_out <= "00000000"; + check_next_state(IDLE); + wait for CLK_PERIOD /4; + check_next_state(TX_HEADER); + wait for CLK_PERIOD * 3 / 4; + expected_out <= get_command_bits(WRITE) & "001"; + check_next_state(TX_BODY); wait for CLK_PERIOD; - nsv := check_next_state(TX_HEADER); + expected_out <= "00000001"; + check_next_state(TX_ACK); wait for CLK_PERIOD; - nsv := check_next_state(TX_BODY); + expected_out <= "00000000"; + check_next_state(TX_ACK); wait for CLK_PERIOD; - nsv := check_next_state(TX_ACK); + expected_out <= "00000000"; + check_next_state(IDLE); wait for CLK_PERIOD; - nsv := check_next_state(TX_ACK); + expected_out <= "00000000"; + check_next_state(IDLE); wait for CLK_PERIOD; - nsv := check_next_state(IDLE); + expected_out <= "00000000"; + check_next_state(IDLE); wait for CLK_PERIOD; - nsv := check_next_state(IDLE); + expected_out <= "00000000"; + check_next_state(IDLE); wait for CLK_PERIOD; - nsv := check_next_state(IDLE); + expected_out <= "00000000"; + check_next_state(IDLE); wait for CLK_PERIOD; - nsv := check_next_state(IDLE); + expected_out <= "00000000"; + check_next_state(IDLE); wait for CLK_PERIOD; - nsv := check_next_state(IDLE); + expected_out <= "00000000"; + check_next_state(IDLE); wait for CLK_PERIOD; - nsv := check_next_state(IDLE); - wait for CLK_PERIOD; - nsv := check_next_state(IDLE); + expected_out <= "00000000"; + check_next_state(IDLE); wait for CLK_PERIOD; wait; - end process verify_next_state; + end process verify_signals; command_stimulus: process begin @@ -150,9 +182,12 @@ begin external_stimulus: process begin + rst <= '0'; + wait for CLK_PERIOD / 1000; rst <= '1'; curr_word <= "00000000"; - wait for 3 * CLK_PERIOD; + wait for 999 * CLK_PERIOD / 1000; + wait for 2 * CLK_PERIOD; rst <= '0'; wait for CLK_PERIOD / 2; wait for 3* CLK_PERIOD; @@ -167,24 +202,35 @@ begin wait for 3 * CLK_PERIOD; -- stimulus goes here int_out.write_enable_out <= '1'; - int_out.payload <= "00000000"; + int_out.payload <= "00000001"; wait until int_in.is_full_out = '0'; wait until rising_edge(clk); + wait until rising_edge(clk); int_out.payload <= "00000010"; wait until int_in.is_full_out = '0'; + wait for CLK_PERIOD/2; + wait until rising_edge(clk); wait until rising_edge(clk); int_out.payload <= "00000100"; wait until int_in.is_full_out = '0'; + wait for CLK_PERIOD/2; + wait until rising_edge(clk); wait until rising_edge(clk); int_out.payload <= "00001000"; wait until int_in.is_full_out = '0'; + wait for CLK_PERIOD/2; + wait until rising_edge(clk); wait until rising_edge(clk); int_out.payload <= "00010000"; wait until int_in.is_full_out = '0'; + wait for CLK_PERIOD/2; + wait until rising_edge(clk); wait until rising_edge(clk); int_out.payload <= "00100000"; wait until int_in.is_full_out = '0'; + wait for CLK_PERIOD/2; wait until rising_edge(clk); + wait until rising_edge(clk); --- ??? Why all these rising_edge checks? wait; end process internal_stimulus; diff --git a/src/socbridge_driver_tb_pkg.vhd b/src/socbridge_driver_tb_pkg.vhd index 676b6ef..10dad39 100644 --- a/src/socbridge_driver_tb_pkg.vhd +++ b/src/socbridge_driver_tb_pkg.vhd @@ -27,9 +27,6 @@ package socbridge_driver_tb_pkg is impure function calc_parity( d : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0) ) return std_logic; - pure function create_ext_protocol_from_io_type_in ( - input : ext_socbridge_in_t - ) return ext_protocol_t; pure function create_io_type_out_from_ext_protocol( input: ext_protocol_t ) return ext_socbridge_out_t; @@ -43,7 +40,7 @@ package socbridge_driver_tb_pkg is signal G_next_state : state_t; signal G_curr_command : command_t; signal G_curr_command_bits : std_logic_vector(4 downto 0); - signal G_curr_respoonse : response_t; + signal G_curr_response : response_t; signal G_curr_response_bits : std_logic_vector(4 downto 0); signal G_st : state_rec_t; -- synthesis translate_on @@ -74,16 +71,6 @@ package body socbridge_driver_tb_pkg is return not parity; end function; - pure function create_ext_protocol_from_io_type_in( - input : ext_socbridge_in_t - ) return ext_protocol_t is - variable val : ext_protocol_t; - begin - val.data := input.payload; - val.clk := input.control(1); - val.parity := input.control(0); - return val; - end function; pure function create_io_type_out_from_ext_protocol( input : ext_protocol_t ) return ext_socbridge_out_t is From 2149c1ec685611da035efa1669ce228a57b7059d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Thu, 27 Feb 2025 16:11:16 +0100 Subject: [PATCH 14/40] added support for multi word writes --- src/socbridge_driver.vhd | 108 +++++++++++++++++++++----------- src/socbridge_driver_tb.vhd | 33 +++++----- src/socbridge_driver_tb_pkg.vhd | 24 +++++++ 3 files changed, 110 insertions(+), 55 deletions(-) diff --git a/src/socbridge_driver.vhd b/src/socbridge_driver.vhd index d0abb8f..19c0834 100644 --- a/src/socbridge_driver.vhd +++ b/src/socbridge_driver.vhd @@ -11,6 +11,7 @@ entity socbridge_driver is clk : in std_logic; rst : in std_logic; cmd : in command_t; + cmd_size: in positive; ext_in : in ext_socbridge_in_t; ext_out : out ext_socbridge_out_t; int_in : out int_socbridge_in_t; @@ -47,36 +48,36 @@ begin ext_in_rec.clk <= ext_in.control(1); ext_in_rec.parity <= ext_in.control(0); - comb_proc: process(ext_in, int_out, st) + -- Helpful Bindings -- + curr_response_bits <= ext_in.payload(7 downto 3); -- CANT USE EXT_IN_REC here for some reason, the assignment becomes stasteful + -- Not sure that the two process method is helping here: if this was a normal + -- signal assignment there would be no confusion. + -- in the case ... <= ext_in_rec we get + -- curr_resp | ext_in_rec | ext_in + -- 00000 | 00000000 | 00001001 + -- 00000 | 00001001 | 00001001 + -- 00001 | 00001001 | 00001001 + -- 00001 | 00001001 | 00001001 + -- + -- but in the case ... <= ext_in we get + -- curr_resp | ext_in_rec | ext_in + -- 00000 | 00000000 | 00001001 + -- 00001 | 00001001 | 00001001 + -- 00001 | 00001001 | 00001001 + -- 00001 | 00001001 | 00001001 + + with curr_response_bits select + curr_response <= WRITE_ACK when "00001", + WRITE_ACK when "00101", + READ_RESPONSE when "01000", + READ_RESPONSE when "01100", + NO_OP when others; + comb_proc: process(ext_in, int_out, curr_response, st) begin -- Outputs ext_out <= create_io_type_out_from_ext_protocol(st.ext_out_reg); int_in.payload <= st.ext_in_reg.data; - -- Helpful Bindings -- - curr_response_bits <= ext_in.payload(7 downto 3); -- CANT USE EXT_IN_REC here for some reason, the assignment becomes stasteful - -- Not sure that the two process method is helping here: if this was a normal - -- signal assignment there would be no confusion. - -- in the case ... <= ext_in_rec we get - -- curr_resp | ext_in_rec | ext_in - -- 00000 | 00000000 | 00001001 - -- 00000 | 00001001 | 00001001 - -- 00001 | 00001001 | 00001001 - -- 00001 | 00001001 | 00001001 - -- - -- but in the case ... <= ext_in we get - -- curr_resp | ext_in_rec | ext_in - -- 00000 | 00000000 | 00001001 - -- 00001 | 00001001 | 00001001 - -- 00001 | 00001001 | 00001001 - -- 00001 | 00001001 | 00001001 - - with curr_response_bits select - curr_response <= WRITE_ACK when "00001", - WRITE_ACK when "00101", - READ_RESPONSE when "01000", - READ_RESPONSE when "01100", - NO_OP when others; --- State Transition Diagram --- -- @@ -122,7 +123,11 @@ begin when TX_BODY => -- Here we want to stay in TX_BODY for the duration of a packet. -- Right now, we transfer one single word at a time for simplicity - next_state <= TX_ACK; + if st.write_stage = 0 then + next_state <= TX_ACK; + else + next_state <= TX_BODY; + end if; when TX_ACK => -- Wait for write acknowledgement. if curr_response = WRITE_ACK then @@ -154,25 +159,31 @@ begin case st.curr_state is when IDLE => if cmd = WRITE or cmd = WRITE_ADD then - ext_out_data_cmd := get_command_bits(WRITE) & "001"; + curr_command <= cmd; + ext_out_data_cmd := get_command_bits(cmd) & get_size_bits(cmd_size); elsif cmd = READ or cmd = READ_ADD then - ext_out_data_cmd := get_command_bits(READ) & "001"; + curr_command <= cmd; + ext_out_data_cmd := get_command_bits(cmd) & get_size_bits(cmd_size); end if; when RESET => when TX_HEADER => - curr_command <= WRITE; - ext_out_data_cmd := int_out.payload; + if cmd = WRITE_ADD then + --ext_out_data_cmd := address; + else + ext_out_data_cmd := int_out.payload; + end if; int_in.is_full_out <= '0'; when TX_BODY => - -- here more logic is needed for mulit word transmission (and address setting) - if cmd = WRITE_ADD then + if curr_response = WRITE_ACK then + ext_out_data_cmd := "00000000"; + else ext_out_data_cmd := int_out.payload; int_in.is_full_out <= '0'; end if; when TX_ACK => when RX_HEADER => curr_command <= READ; - ext_out_data_cmd := curr_command_bits & "001"; + ext_out_data_cmd := curr_command_bits & get_size_bits(cmd_size); when RX_RESPONSE => when RX_BODY => end case; @@ -180,9 +191,6 @@ begin --- DEBUG GLOBAL BINDINGS --- -- synthesis translate_off test <= ext_out_data_cmd; - report to_string(ext_out_data_cmd); - report to_string(test); - report to_string(G_ext_out_data_cmd); -- synthesis translate_on end process comb_proc; -- Process updating internal registers based on primary clock @@ -194,6 +202,8 @@ begin st.ext_out_reg.clk <= '0'; st.ext_out_reg.parity <= '1'; st.curr_state <= IDLE; + st.write_stage <= 0; + st.read_stage <= 0; elsif(rising_edge(ext_in_rec.clk)) then st.ext_in_reg.data <= ext_in_rec.data; @@ -203,7 +213,31 @@ begin st.ext_out_reg.clk <= not st.ext_out_reg.clk; st.ext_out_reg.parity <= next_parity_out; st.curr_state <= next_state; - end if; + case st.curr_state is + when TX_HEADER => + if curr_command = WRITE then + st.write_stage <= 2**(cmd_size - 1) - 1; + elsif curr_command = WRITE_ADD then + st.write_stage <= 2**(cmd_size - 1); + end if; + when TX_BODY => + if st.write_stage > 0 then + st.write_stage <= st.write_stage - 1; + end if; + when RX_HEADER => + if curr_command = READ then + st.read_stage <= 2**(cmd_size - 1) - 1; + elsif curr_command = WRITE_ADD then + st.read_stage <= 2**(cmd_size - 1); + end if; + when RX_BODY => + if st.read_stage > 0 then + st.read_stage <= st.read_stage - 1; + end if; + when others => + end case; + end if; + end process seq_proc; diff --git a/src/socbridge_driver_tb.vhd b/src/socbridge_driver_tb.vhd index 88d4137..65f196d 100644 --- a/src/socbridge_driver_tb.vhd +++ b/src/socbridge_driver_tb.vhd @@ -13,6 +13,7 @@ architecture tb of socbridge_driver_tb is signal clk : std_logic := '0'; signal rst : std_logic; signal cmd : command_t; + signal cmd_size : positive; signal ext_in : ext_socbridge_in_t; signal ext_out : ext_socbridge_out_t; signal int_in : int_socbridge_in_t; @@ -61,6 +62,7 @@ architecture tb of socbridge_driver_tb is clk : in std_logic; rst : in std_logic; cmd : in command_t; + cmd_size: in positive; ext_in : in ext_socbridge_in_t; ext_out : out ext_socbridge_out_t; int_in : out int_socbridge_in_t; @@ -74,6 +76,7 @@ begin clk => clk, rst => rst, cmd => cmd, + cmd_size => cmd_size, ext_in => ext_in, ext_out => ext_out, int_in => int_in, @@ -127,13 +130,13 @@ begin wait for CLK_PERIOD /4; check_next_state(TX_HEADER); wait for CLK_PERIOD * 3 / 4; - expected_out <= get_command_bits(WRITE) & "001"; + expected_out <= get_command_bits(WRITE) & get_size_bits_sim(2); check_next_state(TX_BODY); wait for CLK_PERIOD; expected_out <= "00000001"; - check_next_state(TX_ACK); + check_next_state(TX_BODY); wait for CLK_PERIOD; - expected_out <= "00000000"; + expected_out <= "00000010"; check_next_state(TX_ACK); wait for CLK_PERIOD; expected_out <= "00000000"; @@ -166,6 +169,7 @@ begin command_stimulus: process begin cmd <= NO_OP; + cmd_size <= 2; wait for 3*CLK_PERIOD; wait for CLK_PERIOD / 2; cmd <= WRITE; @@ -203,24 +207,17 @@ begin -- stimulus goes here int_out.write_enable_out <= '1'; int_out.payload <= "00000001"; - wait until int_in.is_full_out = '0'; - wait until rising_edge(clk); - wait until rising_edge(clk); + wait until rising_edge(clk) and int_in.is_full_out = '0'; + wait until falling_edge(clk); int_out.payload <= "00000010"; - wait until int_in.is_full_out = '0'; - wait for CLK_PERIOD/2; - wait until rising_edge(clk); - wait until rising_edge(clk); + wait until rising_edge(clk) and int_in.is_full_out = '0'; + wait until falling_edge(clk); int_out.payload <= "00000100"; - wait until int_in.is_full_out = '0'; - wait for CLK_PERIOD/2; - wait until rising_edge(clk); - wait until rising_edge(clk); + wait until rising_edge(clk) and int_in.is_full_out = '0'; + wait until falling_edge(clk); int_out.payload <= "00001000"; - wait until int_in.is_full_out = '0'; - wait for CLK_PERIOD/2; - wait until rising_edge(clk); - wait until rising_edge(clk); + wait until rising_edge(clk) and int_in.is_full_out = '0'; + wait until falling_edge(clk); int_out.payload <= "00010000"; wait until int_in.is_full_out = '0'; wait for CLK_PERIOD/2; diff --git a/src/socbridge_driver_tb_pkg.vhd b/src/socbridge_driver_tb_pkg.vhd index 10dad39..6723108 100644 --- a/src/socbridge_driver_tb_pkg.vhd +++ b/src/socbridge_driver_tb_pkg.vhd @@ -1,10 +1,14 @@ library IEEE; use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; +use IEEE.MATH_REAL.all; library work; use work.io_types.all; package socbridge_driver_tb_pkg is + subtype command_size_t is integer range 1 to 128; + type command_t is (NO_OP, WRITE_ADD, WRITE, READ_ADD, READ, P_ERR); @@ -23,6 +27,7 @@ package socbridge_driver_tb_pkg is type state_rec_t is record curr_state: state_t; ext_in_reg, ext_out_reg : ext_protocol_t; + write_stage, read_stage : NATURAL; end record state_rec_t; impure function calc_parity( d : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0) @@ -32,6 +37,8 @@ package socbridge_driver_tb_pkg is ) return ext_socbridge_out_t; function to_string ( a: std_logic_vector) return string; pure function get_command_bits(command : command_t) return std_logic_vector; + pure function get_size_bits(size : command_size_t) return std_logic_vector; + pure function get_size_bits_sim(size : command_size_t) return std_logic_vector; --- DEBUG GLOBAL SIGNALS --- -- synthesis translate_off signal G_next_parity_out : std_logic; @@ -96,4 +103,21 @@ package body socbridge_driver_tb_pkg is return val; end function; + + pure function get_size_bits(size: command_size_t) + return std_logic_vector is + variable val : std_logic_vector(2 downto 0); + begin + val := std_logic_vector(TO_UNSIGNED(size - 1, 3)); + return val; + end function; + pure function get_size_bits_sim(size: command_size_t) + return std_logic_vector is + variable pow : integer; + variable val : std_logic_vector(2 downto 0); + begin + pow := integer(CEIL(sqrt(Real(size)))); + val := std_logic_vector(TO_UNSIGNED(size - 1, 3)); + return val; + end function; end package body socbridge_driver_tb_pkg; From 547ff21a538f9a3316d60c972133cb283a67b6de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Mon, 3 Mar 2025 17:13:16 +0100 Subject: [PATCH 15/40] in progress of adding addressing for write command --- src/socbridge_driver.vhd | 97 ++++++++++++++++++++------------- src/socbridge_driver_tb.vhd | 2 +- src/socbridge_driver_tb_pkg.vhd | 10 +++- 3 files changed, 67 insertions(+), 42 deletions(-) diff --git a/src/socbridge_driver.vhd b/src/socbridge_driver.vhd index 19c0834..3b6336e 100644 --- a/src/socbridge_driver.vhd +++ b/src/socbridge_driver.vhd @@ -11,6 +11,7 @@ entity socbridge_driver is clk : in std_logic; rst : in std_logic; cmd : in command_t; + address : in std_logic_vector(31 downto 0); cmd_size: in positive; ext_in : in ext_socbridge_in_t; ext_out : out ext_socbridge_out_t; @@ -26,8 +27,7 @@ architecture rtl of socbridge_driver is shared variable ext_out_data_cmd : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); signal test : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); signal next_state : state_t; - signal curr_command : command_t; - signal curr_command_bits : std_logic_vector(4 downto 0); + signal curr_cmd_bits : std_logic_vector(4 downto 0); signal curr_response : response_t; signal curr_response_bits : std_logic_vector(4 downto 0); signal st : state_rec_t; @@ -38,8 +38,7 @@ begin G_ext_in_rec <= ext_in_rec; G_next_state <= next_state; G_ext_out_data_cmd <=test; - G_curr_command <= curr_command; - G_curr_command_bits <= curr_command_bits; + G_curr_command_bits <= curr_cmd_bits; G_curr_response <= curr_response; G_curr_response_bits <= curr_response_bits; G_st <= st; @@ -81,19 +80,32 @@ begin --- State Transition Diagram --- -- --- +-----+ --- \|/ | --- RESET --+ --- | --- | +-- +-- +-- +-----+ +-- | | +-- \|/ /--+ -- IDLE<-------------------+ -- / \ | -- / \ | -- / \ | -- \|/ \|/ | -- TX_HEADER RX_HEADER | --- | | | --- | | ----+ | +-- |\ / | | +-- | \ / | | +-- | ADDR1 | | +-- | | | | +-- | \|/ | | +-- | ADDR2 | | +-- | | | | +-- | \|/ | | +-- | ADDR3 | | +-- | | | | +-- | \|/ | | +-- | ADDR4 | | +-- | /\ | | +-- | / \ | | +-- |-+ +----| +---+ | -- \|/ \|/ \|/ | | -- TX_BODY RX_RESPONSE---+ | -- | | | @@ -114,8 +126,6 @@ begin else next_state <= IDLE; end if; - when RESET => - next_state <= IDLE; when TX_HEADER => -- The header only takes one word (cycle) to transmit. -- Continue to body directly afterwards. @@ -150,6 +160,16 @@ begin -- Here we want to stay in RX_BODY for the duration of a packet. -- Right now, we receive only one single word at a time for simplicity next_state <= IDLE; + when ADDR1 => + next_state <= ADDR2; + when ADDR2 => + next_state <= ADDR3; + when ADDR3 => + if st.cmd_reg = WRITE or st.cmd_reg = WRITE_ADD then + next_state <= TX_BODY; + else + next_state <= RX_BODY; + end if; end case; --- Combinatorial output based on current state --- @@ -158,34 +178,27 @@ begin int_in.write_enable_in <= '0'; case st.curr_state is when IDLE => - if cmd = WRITE or cmd = WRITE_ADD then - curr_command <= cmd; - ext_out_data_cmd := get_command_bits(cmd) & get_size_bits(cmd_size); - elsif cmd = READ or cmd = READ_ADD then - curr_command <= cmd; - ext_out_data_cmd := get_command_bits(cmd) & get_size_bits(cmd_size); - end if; - when RESET => when TX_HEADER => - if cmd = WRITE_ADD then - --ext_out_data_cmd := address; - else - ext_out_data_cmd := int_out.payload; - end if; - int_in.is_full_out <= '0'; - when TX_BODY => - if curr_response = WRITE_ACK then - ext_out_data_cmd := "00000000"; + if st.cmd_reg = WRITE_ADD then + ext_out_data_cmd := st.addr_reg(7 downto 0); else ext_out_data_cmd := int_out.payload; int_in.is_full_out <= '0'; end if; + when TX_BODY => + ext_out_data_cmd := int_out.payload; + int_in.is_full_out <= '0'; when TX_ACK => when RX_HEADER => - curr_command <= READ; - ext_out_data_cmd := curr_command_bits & get_size_bits(cmd_size); + ext_out_data_cmd := get_cmd_bits(st.cmd_reg) & get_size_bits(cmd_size); when RX_RESPONSE => when RX_BODY => + when ADDR1 => + ext_out_data_cmd := st.addr_reg(15 downto 8); + when ADDR2 => + ext_out_data_cmd := st.addr_reg(23 downto 16); + when ADDR3 => + ext_out_data_cmd := st.addr_reg(31 downto 24); end case; next_parity_out <= calc_parity(ext_out_data_cmd); --- DEBUG GLOBAL BINDINGS --- @@ -204,6 +217,8 @@ begin st.curr_state <= IDLE; st.write_stage <= 0; st.read_stage <= 0; + st.cmd_reg <= NO_OP; + st.addr_reg <= (others => '0'); elsif(rising_edge(ext_in_rec.clk)) then st.ext_in_reg.data <= ext_in_rec.data; @@ -214,21 +229,27 @@ begin st.ext_out_reg.parity <= next_parity_out; st.curr_state <= next_state; case st.curr_state is + when IDLE => + if cmd = WRITE or cmd = WRITE_ADD or + cmd = READ or cmd = READ_ADD then + st.addr_reg <= address; + st.cmd_reg <= cmd; + end if; when TX_HEADER => - if curr_command = WRITE then + if st.cmd_reg = WRITE then st.write_stage <= 2**(cmd_size - 1) - 1; - elsif curr_command = WRITE_ADD then - st.write_stage <= 2**(cmd_size - 1); + elsif st.cmd_reg = WRITE_ADD then + st.write_stage <= 2**(cmd_size - 1) + 3; end if; when TX_BODY => if st.write_stage > 0 then st.write_stage <= st.write_stage - 1; end if; when RX_HEADER => - if curr_command = READ then + if st.cmd_reg = READ then st.read_stage <= 2**(cmd_size - 1) - 1; - elsif curr_command = WRITE_ADD then - st.read_stage <= 2**(cmd_size - 1); + elsif st.cmd_reg = READ_ADD then + st.read_stage <= 2**(cmd_size - 1) + 3; end if; when RX_BODY => if st.read_stage > 0 then diff --git a/src/socbridge_driver_tb.vhd b/src/socbridge_driver_tb.vhd index 65f196d..2bcf280 100644 --- a/src/socbridge_driver_tb.vhd +++ b/src/socbridge_driver_tb.vhd @@ -130,7 +130,7 @@ begin wait for CLK_PERIOD /4; check_next_state(TX_HEADER); wait for CLK_PERIOD * 3 / 4; - expected_out <= get_command_bits(WRITE) & get_size_bits_sim(2); + expected_out <= get_cmd_bits(WRITE) & get_size_bits_sim(2); check_next_state(TX_BODY); wait for CLK_PERIOD; expected_out <= "00000001"; diff --git a/src/socbridge_driver_tb_pkg.vhd b/src/socbridge_driver_tb_pkg.vhd index 6723108..d174742 100644 --- a/src/socbridge_driver_tb_pkg.vhd +++ b/src/socbridge_driver_tb_pkg.vhd @@ -16,7 +16,9 @@ package socbridge_driver_tb_pkg is (NO_OP, WRITE_ACK, READ_RESPONSE); type state_t is - (RESET, IDLE, TX_HEADER, TX_BODY, TX_ACK, RX_HEADER, RX_RESPONSE, RX_BODY); + (IDLE, ADDR1, ADDR2, ADDR3, + TX_HEADER, TX_BODY, TX_ACK, + RX_HEADER, RX_RESPONSE, RX_BODY); type ext_protocol_t is record data : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); @@ -28,6 +30,8 @@ package socbridge_driver_tb_pkg is curr_state: state_t; ext_in_reg, ext_out_reg : ext_protocol_t; write_stage, read_stage : NATURAL; + cmd_reg : command_t; + addr_reg : std_logic_vector(31 downto 0); end record state_rec_t; impure function calc_parity( d : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0) @@ -36,7 +40,7 @@ package socbridge_driver_tb_pkg is input: ext_protocol_t ) return ext_socbridge_out_t; function to_string ( a: std_logic_vector) return string; - pure function get_command_bits(command : command_t) return std_logic_vector; + pure function get_cmd_bits(command : command_t) return std_logic_vector; pure function get_size_bits(size : command_size_t) return std_logic_vector; pure function get_size_bits_sim(size : command_size_t) return std_logic_vector; --- DEBUG GLOBAL SIGNALS --- @@ -88,7 +92,7 @@ package body socbridge_driver_tb_pkg is val.control(0) := input.parity; return val; end function; - pure function get_command_bits(command : command_t) + pure function get_cmd_bits(command : command_t) return std_logic_vector is variable val : std_logic_vector(4 downto 0); begin From a5c9190e2dae87d6f73bbb01dc7286bc612e7dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Tue, 4 Mar 2025 16:06:30 +0100 Subject: [PATCH 16/40] added support for multi word addressable writes --- src/socbridge_driver.vhd | 47 ++++++++++++++++++++++++--------- src/socbridge_driver_tb.vhd | 41 ++++++++++++++++++++++++++-- src/socbridge_driver_tb_pkg.vhd | 2 +- 3 files changed, 75 insertions(+), 15 deletions(-) diff --git a/src/socbridge_driver.vhd b/src/socbridge_driver.vhd index 3b6336e..c6f2cbb 100644 --- a/src/socbridge_driver.vhd +++ b/src/socbridge_driver.vhd @@ -71,7 +71,7 @@ begin READ_RESPONSE when "01000", READ_RESPONSE when "01100", NO_OP when others; - comb_proc: process(ext_in, int_out, curr_response, st) + comb_proc: process(ext_in, int_out, curr_response, st, cmd) begin -- Outputs ext_out <= create_io_type_out_from_ext_protocol(st.ext_out_reg); @@ -128,8 +128,12 @@ begin end if; when TX_HEADER => -- The header only takes one word (cycle) to transmit. - -- Continue to body directly afterwards. - next_state <= TX_BODY; + -- Continue to body or address directly afterwards. + if st.cmd_reg = WRITE_ADD then + next_state <= ADDR1; + else + next_state <= TX_BODY; + end if; when TX_BODY => -- Here we want to stay in TX_BODY for the duration of a packet. -- Right now, we transfer one single word at a time for simplicity @@ -148,7 +152,11 @@ begin when RX_HEADER => -- The header only takes one word (cycle) to transmit. -- Continue to awaiting response directly afterwards. - next_state <= RX_RESPONSE; + if st.cmd_reg = WRITE_ADD then + next_state <= ADDR1; + else + next_state <= RX_RESPONSE; + end if; when RX_RESPONSE => -- Wait for read response. if curr_response = READ_RESPONSE then @@ -165,6 +173,8 @@ begin when ADDR2 => next_state <= ADDR3; when ADDR3 => + next_state <= ADDR4; + when ADDR4 => if st.cmd_reg = WRITE or st.cmd_reg = WRITE_ADD then next_state <= TX_BODY; else @@ -178,6 +188,11 @@ begin int_in.write_enable_in <= '0'; case st.curr_state is when IDLE => + if cmd = WRITE or cmd = WRITE_ADD then + ext_out_data_cmd := get_cmd_bits(cmd) & get_size_bits(cmd_size); + elsif cmd = READ or cmd = READ_ADD then + ext_out_data_cmd := get_cmd_bits(cmd) & get_size_bits(cmd_size); + end if; when TX_HEADER => if st.cmd_reg = WRITE_ADD then ext_out_data_cmd := st.addr_reg(7 downto 0); @@ -186,8 +201,13 @@ begin int_in.is_full_out <= '0'; end if; when TX_BODY => - ext_out_data_cmd := int_out.payload; - int_in.is_full_out <= '0'; + if st.write_stage > 0 then + int_in.is_full_out <= '0'; + ext_out_data_cmd := int_out.payload; + else + ext_out_data_cmd := (others => '0'); + end if; + when TX_ACK => when RX_HEADER => ext_out_data_cmd := get_cmd_bits(st.cmd_reg) & get_size_bits(cmd_size); @@ -199,6 +219,9 @@ begin ext_out_data_cmd := st.addr_reg(23 downto 16); when ADDR3 => ext_out_data_cmd := st.addr_reg(31 downto 24); + when ADDR4 => + int_in.is_full_out <= '0'; + ext_out_data_cmd := int_out.payload; end case; next_parity_out <= calc_parity(ext_out_data_cmd); --- DEBUG GLOBAL BINDINGS --- @@ -236,20 +259,20 @@ begin st.cmd_reg <= cmd; end if; when TX_HEADER => - if st.cmd_reg = WRITE then + if st.cmd_reg = WRITE_ADD then + st.write_stage <= 2**(cmd_size - 1) - 1; + else st.write_stage <= 2**(cmd_size - 1) - 1; - elsif st.cmd_reg = WRITE_ADD then - st.write_stage <= 2**(cmd_size - 1) + 3; end if; when TX_BODY => if st.write_stage > 0 then st.write_stage <= st.write_stage - 1; end if; when RX_HEADER => - if st.cmd_reg = READ then + if st.cmd_reg = READ_ADD then + st.read_stage <= 2**(cmd_size - 1); + else st.read_stage <= 2**(cmd_size - 1) - 1; - elsif st.cmd_reg = READ_ADD then - st.read_stage <= 2**(cmd_size - 1) + 3; end if; when RX_BODY => if st.read_stage > 0 then diff --git a/src/socbridge_driver_tb.vhd b/src/socbridge_driver_tb.vhd index 2bcf280..e99093b 100644 --- a/src/socbridge_driver_tb.vhd +++ b/src/socbridge_driver_tb.vhd @@ -13,6 +13,7 @@ architecture tb of socbridge_driver_tb is signal clk : std_logic := '0'; signal rst : std_logic; signal cmd : command_t; + signal address : std_logic_vector(31 downto 0); signal cmd_size : positive; signal ext_in : ext_socbridge_in_t; signal ext_out : ext_socbridge_out_t; @@ -62,6 +63,7 @@ architecture tb of socbridge_driver_tb is clk : in std_logic; rst : in std_logic; cmd : in command_t; + address : in std_logic_vector(31 downto 0); cmd_size: in positive; ext_in : in ext_socbridge_in_t; ext_out : out ext_socbridge_out_t; @@ -76,6 +78,7 @@ begin clk => clk, rst => rst, cmd => cmd, + address => address, cmd_size => cmd_size, ext_in => ext_in, ext_out => ext_out, @@ -140,7 +143,7 @@ begin check_next_state(TX_ACK); wait for CLK_PERIOD; expected_out <= "00000000"; - check_next_state(IDLE); + check_next_state(TX_ACK); wait for CLK_PERIOD; expected_out <= "00000000"; check_next_state(IDLE); @@ -162,7 +165,30 @@ begin wait for CLK_PERIOD; expected_out <= "00000000"; check_next_state(IDLE); + wait for CLK_PERIOD /4; + check_next_state(TX_HEADER); + wait for CLK_PERIOD * 3 / 4; + expected_out <= get_cmd_bits(WRITE_ADD) & get_size_bits(2); + check_next_state(ADDR1); wait for CLK_PERIOD; + expected_out <= x"FA"; + check_next_state(ADDR2); + wait for CLK_PERIOD; + expected_out <= x"A0"; + check_next_state(ADDR3); + wait for CLK_PERIOD; + expected_out <= x"0F"; + check_next_state(ADDR4); + wait for CLK_PERIOD; + expected_out <= x"FA"; + check_next_state(TX_BODY); + wait for CLK_PERIOD; + expected_out <= "00000100"; + check_next_state(TX_BODY); + wait for CLK_PERIOD; + expected_out <= "00001000"; + wait for CLK_PERIOD; + expected_out <= "00000000"; wait; end process verify_signals; @@ -175,6 +201,12 @@ begin cmd <= WRITE; wait for CLK_PERIOD; cmd <= NO_OP; + wait for CLK_PERIOD * 10; + cmd <= WRITE_ADD; + address <= x"FA0FA0FA"; + wait for CLK_PERIOD; + cmd <= NO_OP; + address <= (others => '0'); wait; end process command_stimulus; @@ -194,8 +226,13 @@ begin wait for 2 * CLK_PERIOD; rst <= '0'; wait for CLK_PERIOD / 2; - wait for 3* CLK_PERIOD; + wait for 4* CLK_PERIOD; curr_word <= "00001001"; + wait for CLK_PERIOD; + curr_word <= "00000000"; + wait for CLK_PERIOD * 10; + curr_word <= "00101001"; + wait; end process external_stimulus; diff --git a/src/socbridge_driver_tb_pkg.vhd b/src/socbridge_driver_tb_pkg.vhd index d174742..19b7b7a 100644 --- a/src/socbridge_driver_tb_pkg.vhd +++ b/src/socbridge_driver_tb_pkg.vhd @@ -16,7 +16,7 @@ package socbridge_driver_tb_pkg is (NO_OP, WRITE_ACK, READ_RESPONSE); type state_t is - (IDLE, ADDR1, ADDR2, ADDR3, + (IDLE, ADDR1, ADDR2, ADDR3, ADDR4, TX_HEADER, TX_BODY, TX_ACK, RX_HEADER, RX_RESPONSE, RX_BODY); From c522997e79d5135b8cb1fe974943390cbee0bccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Tue, 4 Mar 2025 17:10:48 +0100 Subject: [PATCH 17/40] added support for reads with and without addresses --- src/socbridge_driver.vhd | 45 +++++++------- src/socbridge_driver_tb.vhd | 102 ++++++++++++++++++++++++++------ src/socbridge_driver_tb_pkg.vhd | 4 +- 3 files changed, 110 insertions(+), 41 deletions(-) diff --git a/src/socbridge_driver.vhd b/src/socbridge_driver.vhd index c6f2cbb..9261c85 100644 --- a/src/socbridge_driver.vhd +++ b/src/socbridge_driver.vhd @@ -75,7 +75,6 @@ begin begin -- Outputs ext_out <= create_io_type_out_from_ext_protocol(st.ext_out_reg); - int_in.payload <= st.ext_in_reg.data; --- State Transition Diagram --- @@ -136,7 +135,6 @@ begin end if; when TX_BODY => -- Here we want to stay in TX_BODY for the duration of a packet. - -- Right now, we transfer one single word at a time for simplicity if st.write_stage = 0 then next_state <= TX_ACK; else @@ -152,7 +150,7 @@ begin when RX_HEADER => -- The header only takes one word (cycle) to transmit. -- Continue to awaiting response directly afterwards. - if st.cmd_reg = WRITE_ADD then + if st.cmd_reg = READ_ADD then next_state <= ADDR1; else next_state <= RX_RESPONSE; @@ -160,15 +158,21 @@ begin when RX_RESPONSE => -- Wait for read response. if curr_response = READ_RESPONSE then - next_state <= RX_BODY; + next_state <= RX_BODY_NO_OUT; else next_state <= RX_RESPONSE; end if; + when RX_BODY_NO_OUT => + next_state <= RX_BODY; when RX_BODY => -- Here we want to stay in RX_BODY for the duration of a packet. - -- Right now, we receive only one single word at a time for simplicity - next_state <= IDLE; + if st.read_stage = 0 then + next_state <= IDLE; + else + next_state <= RX_BODY; + end if; when ADDR1 => + -- Transmits the entire address and returns to the appropriate next_state <= ADDR2; when ADDR2 => next_state <= ADDR3; @@ -178,7 +182,7 @@ begin if st.cmd_reg = WRITE or st.cmd_reg = WRITE_ADD then next_state <= TX_BODY; else - next_state <= RX_BODY; + next_state <= RX_RESPONSE; end if; end case; @@ -186,6 +190,7 @@ begin ext_out_data_cmd := (others => '0'); int_in.is_full_out <= '1'; int_in.write_enable_in <= '0'; + int_in.payload <= (others => '0'); case st.curr_state is when IDLE => if cmd = WRITE or cmd = WRITE_ADD then @@ -207,12 +212,16 @@ begin else ext_out_data_cmd := (others => '0'); end if; - when TX_ACK => when RX_HEADER => - ext_out_data_cmd := get_cmd_bits(st.cmd_reg) & get_size_bits(cmd_size); + if st.cmd_reg = READ_ADD then + ext_out_data_cmd := st.addr_reg(7 downto 0); + end if; when RX_RESPONSE => + when RX_BODY_NO_OUT => when RX_BODY => + int_in.payload <= st.ext_in_reg.data; + int_in.write_enable_in <= '1'; when ADDR1 => ext_out_data_cmd := st.addr_reg(15 downto 8); when ADDR2 => @@ -220,8 +229,10 @@ begin when ADDR3 => ext_out_data_cmd := st.addr_reg(31 downto 24); when ADDR4 => - int_in.is_full_out <= '0'; - ext_out_data_cmd := int_out.payload; + if st.cmd_reg = WRITE_ADD then + int_in.is_full_out <= '0'; + ext_out_data_cmd := int_out.payload; + end if; end case; next_parity_out <= calc_parity(ext_out_data_cmd); --- DEBUG GLOBAL BINDINGS --- @@ -259,21 +270,13 @@ begin st.cmd_reg <= cmd; end if; when TX_HEADER => - if st.cmd_reg = WRITE_ADD then - st.write_stage <= 2**(cmd_size - 1) - 1; - else - st.write_stage <= 2**(cmd_size - 1) - 1; - end if; + st.write_stage <= 2**(cmd_size - 1) - 1; when TX_BODY => if st.write_stage > 0 then st.write_stage <= st.write_stage - 1; end if; when RX_HEADER => - if st.cmd_reg = READ_ADD then - st.read_stage <= 2**(cmd_size - 1); - else - st.read_stage <= 2**(cmd_size - 1) - 1; - end if; + st.read_stage <= 2**(cmd_size - 1) - 1; when RX_BODY => if st.read_stage > 0 then st.read_stage <= st.read_stage - 1; diff --git a/src/socbridge_driver_tb.vhd b/src/socbridge_driver_tb.vhd index e99093b..ae74ab4 100644 --- a/src/socbridge_driver_tb.vhd +++ b/src/socbridge_driver_tb.vhd @@ -145,24 +145,8 @@ begin expected_out <= "00000000"; check_next_state(TX_ACK); wait for CLK_PERIOD; - expected_out <= "00000000"; check_next_state(IDLE); - wait for CLK_PERIOD; - expected_out <= "00000000"; - check_next_state(IDLE); - wait for CLK_PERIOD; - expected_out <= "00000000"; - check_next_state(IDLE); - wait for CLK_PERIOD; - expected_out <= "00000000"; - check_next_state(IDLE); - wait for CLK_PERIOD; - expected_out <= "00000000"; - check_next_state(IDLE); - wait for CLK_PERIOD; - expected_out <= "00000000"; - check_next_state(IDLE); - wait for CLK_PERIOD; + wait for CLK_PERIOD * 6; expected_out <= "00000000"; check_next_state(IDLE); wait for CLK_PERIOD /4; @@ -187,8 +171,61 @@ begin check_next_state(TX_BODY); wait for CLK_PERIOD; expected_out <= "00001000"; + check_next_state(TX_ACK); wait for CLK_PERIOD; expected_out <= "00000000"; + check_next_state(TX_ACK); + wait for CLK_PERIOD; + expected_out <= "00000000"; + check_next_state(IDLE); + wait for CLK_PERIOD * 2; + wait for CLK_PERIOD /4; + check_next_state(RX_HEADER); + wait for CLK_PERIOD * 3 / 4; + expected_out <= get_cmd_bits(READ) & get_size_bits(2); + check_next_state(RX_RESPONSE); + wait for CLK_PERIOD; + expected_out <= "00000000"; + check_next_state(RX_RESPONSE); + wait for CLK_PERIOD; + wait for CLK_PERIOD / 4; + check_next_state(RX_BODY_NO_OUT); + wait for CLK_PERIOD * 3 /4; + check_next_state(RX_BODY); + wait for CLK_PERIOD; + check_next_state(RX_BODY); + wait for CLK_PERIOD; + check_next_state(IDLE); + wait for CLK_PERIOD * 5; + wait for CLK_PERIOD /4; + check_next_state(RX_HEADER); + wait for CLK_PERIOD * 3 / 4; + expected_out <= get_cmd_bits(READ_ADD) & get_size_bits(2); + check_next_state(ADDR1); + wait for CLK_PERIOD; + expected_out <= x"FA"; + check_next_state(ADDR2); + wait for CLK_PERIOD; + expected_out <= x"A0"; + check_next_state(ADDR3); + wait for CLK_PERIOD; + expected_out <= x"0F"; + check_next_state(ADDR4); + wait for CLK_PERIOD; + expected_out <= x"FA"; + check_next_state(RX_RESPONSE); + wait for CLK_PERIOD; + expected_out <= "00000000"; + check_next_state(RX_RESPONSE); + wait for CLK_PERIOD; + wait for CLK_PERIOD / 4; + check_next_state(RX_BODY_NO_OUT); + wait for CLK_PERIOD * 3 /4; + check_next_state(RX_BODY); + wait for CLK_PERIOD; + check_next_state(RX_BODY); + wait for CLK_PERIOD; + check_next_state(IDLE); wait; end process verify_signals; @@ -207,6 +244,16 @@ begin wait for CLK_PERIOD; cmd <= NO_OP; address <= (others => '0'); + wait for CLK_PERIOD * 10; + cmd <= READ; + wait for CLK_PERIOD; + cmd <= NO_OP; + wait for CLK_PERIOD * 10; + cmd <= READ_ADD; + address <= x"FA0FA0FA"; + wait for CLK_PERIOD; + cmd <= NO_OP; + address <= (others => '0'); wait; end process command_stimulus; @@ -230,8 +277,27 @@ begin curr_word <= "00001001"; wait for CLK_PERIOD; curr_word <= "00000000"; - wait for CLK_PERIOD * 10; + wait for CLK_PERIOD * 14; curr_word <= "00101001"; + wait for CLK_PERIOD; + curr_word <= "00000000"; + wait for CLK_PERIOD*5; + curr_word <= "01000001"; + wait for CLK_PERIOD; + curr_word <= "10000000"; + wait for CLK_PERIOD; + curr_word <= "01000000"; + wait for CLK_PERIOD; + curr_word <= "00000000"; + wait for CLK_PERIOD*12; + curr_word <= "01100001"; + wait for CLK_PERIOD; + curr_word <= "00100000"; + wait for CLK_PERIOD; + curr_word <= "00010000"; + wait for CLK_PERIOD; + curr_word <= "00000000"; + wait; end process external_stimulus; diff --git a/src/socbridge_driver_tb_pkg.vhd b/src/socbridge_driver_tb_pkg.vhd index 19b7b7a..11acdf6 100644 --- a/src/socbridge_driver_tb_pkg.vhd +++ b/src/socbridge_driver_tb_pkg.vhd @@ -16,9 +16,9 @@ package socbridge_driver_tb_pkg is (NO_OP, WRITE_ACK, READ_RESPONSE); type state_t is - (IDLE, ADDR1, ADDR2, ADDR3, ADDR4, + (IDLE, ADDR1, ADDR2, ADDR3, ADDR4, TX_HEADER, TX_BODY, TX_ACK, - RX_HEADER, RX_RESPONSE, RX_BODY); + RX_HEADER, RX_RESPONSE, RX_BODY_NO_OUT, RX_BODY); type ext_protocol_t is record data : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); From 8b0ec9a856bd168b3070c9d5426fb1a2a0a944b0 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 24 Feb 2025 17:13:00 +0100 Subject: [PATCH 18/40] Started working on io for control unit --- src/control_unit.vhd | 34 ++++++++++++++++++++++++++++++++++ src/io_type_pkg.vhd | 9 +++++++++ 2 files changed, 43 insertions(+) create mode 100644 src/control_unit.vhd diff --git a/src/control_unit.vhd b/src/control_unit.vhd new file mode 100644 index 0000000..48273a7 --- /dev/null +++ b/src/control_unit.vhd @@ -0,0 +1,34 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.MATH_REAL.all; +library work; +use work.io_types.all; + +entity control_unit is + + port ( + clk, rst: in std_logic; + address_read_in, address_write_in: in control_unit_ext_t.address; + address_read_out, address_write_out: in control_unit_ext_t.address); + words_to_read_in: in std_logic_vector(control_unit_ext_t.seq_read_count); + words_to_write_in: in std_logic_vector(control_unit_ext_t.seq_write_count); + ); + +end entity control_unit; + +architecture behave of control_unit is + +begin + + main_proc: process(clk) + begin + if rising_edge(clk) then + if rst = '0' then + + else + + end if; + end if; + end process main_proc; + +end architecture behave; diff --git a/src/io_type_pkg.vhd b/src/io_type_pkg.vhd index 3afb8f0..bfac5b1 100644 --- a/src/io_type_pkg.vhd +++ b/src/io_type_pkg.vhd @@ -15,6 +15,15 @@ package io_types is socbridge: ext_protocol_def_t; end record interface_inst_t; + constant number_of_drivers = 3; + + type control_unit_ext_t is record + interface_id_count: in std_logic_vector(number_of_drivers)) downto 0); + address: in std_logic_vector(32 downto 0); + seq_write_count: in std_logic_vector(7 downto 0); + seq_read_count: in std_logic_vector(7 downto 0); + end record control_unit_format; + --- PROTOCOL INFORMATION --- constant interface_inst : interface_inst_t := ( socbridge => ("SoCBridge ", 8, 2, 2) From 848eaf4c7a95bc4dcf4aafc97df8f9d93f94b4be Mon Sep 17 00:00:00 2001 From: Adam Date: Tue, 25 Feb 2025 17:11:29 +0100 Subject: [PATCH 19/40] Started work on control functionality, not tested --- src/control_unit.vhd | 47 ++++++++++++++++++++++++++++++++++---------- src/io_type_pkg.vhd | 17 +++++++++++----- 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/src/control_unit.vhd b/src/control_unit.vhd index 48273a7..668d123 100644 --- a/src/control_unit.vhd +++ b/src/control_unit.vhd @@ -8,27 +8,54 @@ entity control_unit is port ( clk, rst: in std_logic; - address_read_in, address_write_in: in control_unit_ext_t.address; - address_read_out, address_write_out: in control_unit_ext_t.address); - words_to_read_in: in std_logic_vector(control_unit_ext_t.seq_read_count); - words_to_write_in: in std_logic_vector(control_unit_ext_t.seq_write_count); + control_in: in control_unit_in_t; + control_out: out control_unit_out_t ); end entity control_unit; architecture behave of control_unit is - + type state_t is record + address: std_logic_vector(address_width - 1 downto 0); + seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); + curr_driver: std_logic_vector(number_of_drivers - 1 downto 0); --one-hot encoded, 0 means disabled + ready: std_logic + end record type_name; + + signal state: state_t := (others => '0', + others => '0', + others => '0', + '1'); + begin - - main_proc: process(clk) + + comb_proc: process(control_in, control_out, state) + variable ored: std_logic := '0'; + begin + ready_reduction: for i in 0 to number_of_drivers loop + ored <= ored or control_in.active_driver(i); + end loop ready_reduction; + ready <= ored; + end process comb_proc; + + sync_proc: process(clk, state) begin if rising_edge(clk) then if rst = '0' then - + state <= (others => '0', + others => '0', + others => '0'); else - + if state.ready = '1' then + state.address <= control_in.address; + state.seq_mem_access_count <= control_in.seq_mem_access_count; + state.curr_driver <= control_in.driver_id; + end if; + control_out.driver_id <= state.curr_driver; + control_out.address <= state.address; + control_out.seq_mem_access_count <= state.seq_mem_access_count; end if; end if; - end process main_proc; + end process sync_proc; end architecture behave; diff --git a/src/io_type_pkg.vhd b/src/io_type_pkg.vhd index bfac5b1..4af6ee1 100644 --- a/src/io_type_pkg.vhd +++ b/src/io_type_pkg.vhd @@ -16,14 +16,21 @@ package io_types is end record interface_inst_t; constant number_of_drivers = 3; + constant address_width = 32; + constant seq_vector_length = 8; - type control_unit_ext_t is record - interface_id_count: in std_logic_vector(number_of_drivers)) downto 0); - address: in std_logic_vector(32 downto 0); - seq_write_count: in std_logic_vector(7 downto 0); - seq_read_count: in std_logic_vector(7 downto 0); + type control_unit_out_t is record + driver_id: std_logic_vector(number_of_drivers - 1 downto 0); + address: std_logic_vector(address_width - 1 downto 0); + seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); + ready: std_logic end record control_unit_format; + type control_unit_in_t is record + driver_id, active_driver: std_logic_vector(number_of_drivers - 1 downto 0); + address: std_logic_vector(address_width - 1 downto 0); + seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0) + end record control_unit_format; --- PROTOCOL INFORMATION --- constant interface_inst : interface_inst_t := ( socbridge => ("SoCBridge ", 8, 2, 2) From 933e5b66bc992346a7813521fd46864569e1d5b8 Mon Sep 17 00:00:00 2001 From: Adam Magnusson Date: Wed, 26 Feb 2025 18:19:54 +0100 Subject: [PATCH 20/40] started working on control unit testbench --- src/control_unit.vhd | 20 ++++++++--------- src/control_unit_tb.vhd | 49 +++++++++++++++++++++++++++++++++++++++++ src/io_type_pkg.vhd | 14 ++++++------ 3 files changed, 65 insertions(+), 18 deletions(-) create mode 100644 src/control_unit_tb.vhd diff --git a/src/control_unit.vhd b/src/control_unit.vhd index 668d123..f49b14a 100644 --- a/src/control_unit.vhd +++ b/src/control_unit.vhd @@ -19,16 +19,13 @@ architecture behave of control_unit is address: std_logic_vector(address_width - 1 downto 0); seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); curr_driver: std_logic_vector(number_of_drivers - 1 downto 0); --one-hot encoded, 0 means disabled - ready: std_logic - end record type_name; + ready: std_logic; + end record state_t; - signal state: state_t := (others => '0', - others => '0', - others => '0', - '1'); + signal state: state_t; begin - + comb_proc: process(control_in, control_out, state) variable ored: std_logic := '0'; begin @@ -36,6 +33,9 @@ begin ored <= ored or control_in.active_driver(i); end loop ready_reduction; ready <= ored; + control_out.driver_id <= state.curr_driver; + control_out.address <= state.address; + control_out.seq_mem_access_count <= state.seq_mem_access_count; end process comb_proc; sync_proc: process(clk, state) @@ -44,16 +44,14 @@ begin if rst = '0' then state <= (others => '0', others => '0', - others => '0'); + others => '0', + '1'); else if state.ready = '1' then state.address <= control_in.address; state.seq_mem_access_count <= control_in.seq_mem_access_count; state.curr_driver <= control_in.driver_id; end if; - control_out.driver_id <= state.curr_driver; - control_out.address <= state.address; - control_out.seq_mem_access_count <= state.seq_mem_access_count; end if; end if; end process sync_proc; diff --git a/src/control_unit_tb.vhd b/src/control_unit_tb.vhd new file mode 100644 index 0000000..14c9d15 --- /dev/null +++ b/src/control_unit_tb.vhd @@ -0,0 +1,49 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.MATH_REAL.all; +library work; +use work.io_types.all; + +entity control_unit_tb +end entity control_unit_tb; + +architecture tb of control_unit_tb is + + constant cycle := 10 ns; + signal clock := '0'; + signal finished: std_logic; + + + component control_unit is + port( + clk, rst: in std_logic; + control_in: in control_unit_in_t; + control_out: out control_unit_out_t); + end component control_unit; + +begin + + clock <= not clock after cycle / 2 when finished /= '1'; + + control_unit_inst: control_unit + port map( + clk => clock, + rst => reset, + + ); + +stimulus_proc: process +begin + finished <= '0'; + + finished <= '1'; +end process stimulus_proc; + +monitor_proc: process +begin + finished <= '0'; + + finished <= '1'; +end process monitor_proc; + +end architecture tb; diff --git a/src/io_type_pkg.vhd b/src/io_type_pkg.vhd index 4af6ee1..ff8c6c6 100644 --- a/src/io_type_pkg.vhd +++ b/src/io_type_pkg.vhd @@ -15,22 +15,22 @@ package io_types is socbridge: ext_protocol_def_t; end record interface_inst_t; - constant number_of_drivers = 3; - constant address_width = 32; - constant seq_vector_length = 8; + constant number_of_drivers: natural := 3; + constant address_width: natural := 32; + constant seq_vector_length: natural := 8; type control_unit_out_t is record driver_id: std_logic_vector(number_of_drivers - 1 downto 0); address: std_logic_vector(address_width - 1 downto 0); seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); - ready: std_logic - end record control_unit_format; + ready: std_logic; + end record control_unit_out_t; type control_unit_in_t is record driver_id, active_driver: std_logic_vector(number_of_drivers - 1 downto 0); address: std_logic_vector(address_width - 1 downto 0); - seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0) - end record control_unit_format; + seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); + end record control_unit_in_t; --- PROTOCOL INFORMATION --- constant interface_inst : interface_inst_t := ( socbridge => ("SoCBridge ", 8, 2, 2) From e7b47722234bd4c42cad2fb3b2f607c1a4fc4fbd Mon Sep 17 00:00:00 2001 From: Adam Magnusson Date: Fri, 28 Feb 2025 17:03:13 +0100 Subject: [PATCH 21/40] testbench almost done, needs debugging --- src/control_unit.vhd | 18 ++++++------ src/control_unit_tb.vhd | 62 +++++++++++++++++++++++++++++++++-------- 2 files changed, 60 insertions(+), 20 deletions(-) diff --git a/src/control_unit.vhd b/src/control_unit.vhd index f49b14a..b236a27 100644 --- a/src/control_unit.vhd +++ b/src/control_unit.vhd @@ -26,13 +26,13 @@ architecture behave of control_unit is begin - comb_proc: process(control_in, control_out, state) + comb_proc: process(control_in, state) variable ored: std_logic := '0'; begin - ready_reduction: for i in 0 to number_of_drivers loop - ored <= ored or control_in.active_driver(i); + ready_reduction: for i in 0 to number_of_drivers - 1 loop + ored := ored or control_in.active_driver(i); end loop ready_reduction; - ready <= ored; + state.ready <= ored; control_out.driver_id <= state.curr_driver; control_out.address <= state.address; control_out.seq_mem_access_count <= state.seq_mem_access_count; @@ -41,11 +41,11 @@ begin sync_proc: process(clk, state) begin if rising_edge(clk) then - if rst = '0' then - state <= (others => '0', - others => '0', - others => '0', - '1'); + if rst = '1' then + state <= ((others => '0'), + (others => '0'), + (others => '0'), + '0'); else if state.ready = '1' then state.address <= control_in.address; diff --git a/src/control_unit_tb.vhd b/src/control_unit_tb.vhd index 14c9d15..beda742 100644 --- a/src/control_unit_tb.vhd +++ b/src/control_unit_tb.vhd @@ -4,15 +4,27 @@ use IEEE.MATH_REAL.all; library work; use work.io_types.all; -entity control_unit_tb +entity control_unit_tb is end entity control_unit_tb; architecture tb of control_unit_tb is - constant cycle := 10 ns; - signal clock := '0'; - signal finished: std_logic; - + constant cycle: Time := 10 ns; + signal clock: std_logic := '0'; + signal stim_finished, mon_finished: std_logic; + signal reset: std_logic; + signal control_input: control_unit_in_t := ( + (others => '0'), + (others => '0'), + (others => '0'), + (others => '0')); + signal control_output: control_unit_out_t := ( + (others => '0'), + (others => '0'), + (others => '0'), + '0'); + signal current_driver : std_logic_vector(2 downto 0) := "000"; + shared variable word_counter: natural := 0; component control_unit is port( @@ -23,27 +35,55 @@ architecture tb of control_unit_tb is begin - clock <= not clock after cycle / 2 when finished /= '1'; + clock <= not clock after cycle / 2 when (stim_finished and mon_finished) /= '1'; control_unit_inst: control_unit port map( clk => clock, rst => reset, - + control_in => control_input, + control_out => control_output ); stimulus_proc: process begin - finished <= '0'; + stim_finished <= '0'; + + wait for cycle; + + control_input.driver_id <= "010"; + control_input.active_driver <= "000"; + control_input.address <= x"F0F0F0F0"; + control_input.seq_mem_access_count <= "00000111"; - finished <= '1'; + report "entering loop with word_counter" & integer'image(word_counter); + for_loop: for i in word_counter - 1 downto 0 loop + wait for cycle; + report "word counter is " & integer'image(word_counter); + end loop for_loop; + + control_input.active_driver <= "000"; + + stim_finished <= '1'; + wait until mon_finished = '1'; + wait; end process stimulus_proc; monitor_proc: process begin - finished <= '0'; + mon_finished <= '0'; - finished <= '1'; + wait for cycle; + + wait for cycle; + assert control_output.driver_id = "010" report "Incorrect driver_id from control_unit" severity warning; + assert control_output.address = x"F0F0F0F0" report "Incorrect address from control_unit" severity warning; + wait until word_counter = 0; + assert control_output.ready = '1' report "control_unit did not signal ready" severity warning; + + mon_finished <= '1'; + wait until stim_finished = '1'; + wait; end process monitor_proc; end architecture tb; From 968acd4e3abb013b7799e5f299d2a080d1c2dec5 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 3 Mar 2025 16:46:02 +0100 Subject: [PATCH 22/40] testbench debgging --- src/control_unit.vhd | 11 +++++++---- src/control_unit_tb.vhd | 42 ++++++++++++++--------------------------- 2 files changed, 21 insertions(+), 32 deletions(-) diff --git a/src/control_unit.vhd b/src/control_unit.vhd index b236a27..6c67401 100644 --- a/src/control_unit.vhd +++ b/src/control_unit.vhd @@ -23,19 +23,21 @@ architecture behave of control_unit is end record state_t; signal state: state_t; + shared variable ored: std_logic; + begin comb_proc: process(control_in, state) - variable ored: std_logic := '0'; begin + ored := '0'; ready_reduction: for i in 0 to number_of_drivers - 1 loop ored := ored or control_in.active_driver(i); end loop ready_reduction; - state.ready <= ored; control_out.driver_id <= state.curr_driver; control_out.address <= state.address; control_out.seq_mem_access_count <= state.seq_mem_access_count; + control_out.ready <= state.ready; end process comb_proc; sync_proc: process(clk, state) @@ -45,9 +47,10 @@ begin state <= ((others => '0'), (others => '0'), (others => '0'), - '0'); + '1'); else - if state.ready = '1' then + state.ready <= not ored; + if ored = '0' then state.address <= control_in.address; state.seq_mem_access_count <= control_in.seq_mem_access_count; state.curr_driver <= control_in.driver_id; diff --git a/src/control_unit_tb.vhd b/src/control_unit_tb.vhd index beda742..2787f70 100644 --- a/src/control_unit_tb.vhd +++ b/src/control_unit_tb.vhd @@ -1,6 +1,7 @@ library IEEE; use IEEE.std_logic_1164.all; use IEEE.MATH_REAL.all; +use ieee.numeric_std.all; library work; use work.io_types.all; @@ -11,50 +12,41 @@ architecture tb of control_unit_tb is constant cycle: Time := 10 ns; signal clock: std_logic := '0'; - signal stim_finished, mon_finished: std_logic; - signal reset: std_logic; + signal reset: std_logic := '0'; signal control_input: control_unit_in_t := ( (others => '0'), (others => '0'), (others => '0'), - (others => '0')); + "00000011"); signal control_output: control_unit_out_t := ( (others => '0'), (others => '0'), - (others => '0'), - '0'); + (others => '1'), + '1'); signal current_driver : std_logic_vector(2 downto 0) := "000"; shared variable word_counter: natural := 0; - component control_unit is - port( - clk, rst: in std_logic; - control_in: in control_unit_in_t; - control_out: out control_unit_out_t); - end component control_unit; - begin - clock <= not clock after cycle / 2 when (stim_finished and mon_finished) /= '1'; + clock <= not clock after cycle / 2; - control_unit_inst: control_unit + control_unit_inst: entity work.control_unit port map( clk => clock, rst => reset, control_in => control_input, control_out => control_output - ); + ); stimulus_proc: process begin - stim_finished <= '0'; - wait for cycle; control_input.driver_id <= "010"; control_input.active_driver <= "000"; control_input.address <= x"F0F0F0F0"; control_input.seq_mem_access_count <= "00000111"; + word_counter := 3; report "entering loop with word_counter" & integer'image(word_counter); for_loop: for i in word_counter - 1 downto 0 loop @@ -63,26 +55,20 @@ begin end loop for_loop; control_input.active_driver <= "000"; - - stim_finished <= '1'; - wait until mon_finished = '1'; + report "Stim process done"; wait; end process stimulus_proc; monitor_proc: process begin - mon_finished <= '0'; wait for cycle; wait for cycle; - assert control_output.driver_id = "010" report "Incorrect driver_id from control_unit" severity warning; - assert control_output.address = x"F0F0F0F0" report "Incorrect address from control_unit" severity warning; - wait until word_counter = 0; - assert control_output.ready = '1' report "control_unit did not signal ready" severity warning; - - mon_finished <= '1'; - wait until stim_finished = '1'; + assert control_output.driver_id = "010" report "Incorrect driver_id from control_unit" severity error; + assert control_output.address = x"F0F0F0F0" report "Incorrect address from control_unit" severity error; + wait for 5 * cycle; + report "Monitor process done"; wait; end process monitor_proc; From 4c4d62554fe3b1fea5b9e0de9991c6d6d378fa40 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 3 Mar 2025 16:59:06 +0100 Subject: [PATCH 23/40] testbench works --- src/control_unit_tb.vhd | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/control_unit_tb.vhd b/src/control_unit_tb.vhd index 2787f70..0f2ce51 100644 --- a/src/control_unit_tb.vhd +++ b/src/control_unit_tb.vhd @@ -27,8 +27,15 @@ architecture tb of control_unit_tb is shared variable word_counter: natural := 0; begin - - clock <= not clock after cycle / 2; + + clock_proc: process + begin + for i in 0 to 50 loop + wait for cycle / 2; + clock <= not clock; + end loop; + wait; + end process clock_proc; control_unit_inst: entity work.control_unit port map( @@ -47,6 +54,8 @@ begin control_input.address <= x"F0F0F0F0"; control_input.seq_mem_access_count <= "00000111"; word_counter := 3; + wait for cycle; + current_driver <= "010"; report "entering loop with word_counter" & integer'image(word_counter); for_loop: for i in word_counter - 1 downto 0 loop From 7a24dc8febbb4702ea0cdb3fb912325d8529de96 Mon Sep 17 00:00:00 2001 From: Adam Magnusson Date: Tue, 4 Mar 2025 14:54:15 +0100 Subject: [PATCH 24/40] Control unit tested and seems to work for the requirements of the basic version --- src/control_unit.vhd | 7 +++++-- src/control_unit_tb.vhd | 15 +++++++++++---- src/io_type_pkg.vhd | 3 ++- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/control_unit.vhd b/src/control_unit.vhd index 6c67401..64cbe0c 100644 --- a/src/control_unit.vhd +++ b/src/control_unit.vhd @@ -19,7 +19,7 @@ architecture behave of control_unit is address: std_logic_vector(address_width - 1 downto 0); seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); curr_driver: std_logic_vector(number_of_drivers - 1 downto 0); --one-hot encoded, 0 means disabled - ready: std_logic; + ready, is_write: std_logic; end record state_t; signal state: state_t; @@ -38,6 +38,7 @@ begin control_out.address <= state.address; control_out.seq_mem_access_count <= state.seq_mem_access_count; control_out.ready <= state.ready; + control_out.is_write <= state.is_write; end process comb_proc; sync_proc: process(clk, state) @@ -47,13 +48,15 @@ begin state <= ((others => '0'), (others => '0'), (others => '0'), - '1'); + '1', + '0'); else state.ready <= not ored; if ored = '0' then state.address <= control_in.address; state.seq_mem_access_count <= control_in.seq_mem_access_count; state.curr_driver <= control_in.driver_id; + state.is_write <= control_in.is_write; end if; end if; end if; diff --git a/src/control_unit_tb.vhd b/src/control_unit_tb.vhd index 0f2ce51..3921f52 100644 --- a/src/control_unit_tb.vhd +++ b/src/control_unit_tb.vhd @@ -17,12 +17,14 @@ architecture tb of control_unit_tb is (others => '0'), (others => '0'), (others => '0'), - "00000011"); + (others => '0'), + '0'); signal control_output: control_unit_out_t := ( (others => '0'), (others => '0'), (others => '1'), - '1'); + '1', + '0'); signal current_driver : std_logic_vector(2 downto 0) := "000"; shared variable word_counter: natural := 0; @@ -52,7 +54,8 @@ begin control_input.driver_id <= "010"; control_input.active_driver <= "000"; control_input.address <= x"F0F0F0F0"; - control_input.seq_mem_access_count <= "00000111"; + control_input.seq_mem_access_count <= "00000011"; + control_input.is_write <= '1'; word_counter := 3; wait for cycle; current_driver <= "010"; @@ -60,7 +63,7 @@ begin report "entering loop with word_counter" & integer'image(word_counter); for_loop: for i in word_counter - 1 downto 0 loop wait for cycle; - report "word counter is " & integer'image(word_counter); + report "words remaining are " & integer'image(i); end loop for_loop; control_input.active_driver <= "000"; @@ -76,7 +79,11 @@ begin wait for cycle; assert control_output.driver_id = "010" report "Incorrect driver_id from control_unit" severity error; assert control_output.address = x"F0F0F0F0" report "Incorrect address from control_unit" severity error; + assert control_output.is_write = '0' report "Incorrect memory op from control_unit" severity error; + wait for 5 * cycle; + reset <= '1'; + report "Monitor process done"; wait; end process monitor_proc; diff --git a/src/io_type_pkg.vhd b/src/io_type_pkg.vhd index ff8c6c6..ea50409 100644 --- a/src/io_type_pkg.vhd +++ b/src/io_type_pkg.vhd @@ -23,13 +23,14 @@ package io_types is driver_id: std_logic_vector(number_of_drivers - 1 downto 0); address: std_logic_vector(address_width - 1 downto 0); seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); - ready: std_logic; + ready, is_write: std_logic; end record control_unit_out_t; type control_unit_in_t is record driver_id, active_driver: std_logic_vector(number_of_drivers - 1 downto 0); address: std_logic_vector(address_width - 1 downto 0); seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); + is_write: std_logic; end record control_unit_in_t; --- PROTOCOL INFORMATION --- constant interface_inst : interface_inst_t := ( From 2be506209c28a82e10756bbf8c8a9fd0b3697688 Mon Sep 17 00:00:00 2001 From: Adam Magnusson Date: Tue, 4 Mar 2025 16:33:49 +0100 Subject: [PATCH 25/40] Made instruction a byte instead of a bit --- src/control_unit.vhd | 9 +++++---- src/control_unit_tb.vhd | 8 ++++---- src/io_type_pkg.vhd | 6 ++++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/control_unit.vhd b/src/control_unit.vhd index 64cbe0c..7c4095b 100644 --- a/src/control_unit.vhd +++ b/src/control_unit.vhd @@ -19,7 +19,8 @@ architecture behave of control_unit is address: std_logic_vector(address_width - 1 downto 0); seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); curr_driver: std_logic_vector(number_of_drivers - 1 downto 0); --one-hot encoded, 0 means disabled - ready, is_write: std_logic; + ready: std_logic; + instruction: std_logic_vector(inst_word_width - 1 downto 0); end record state_t; signal state: state_t; @@ -38,7 +39,7 @@ begin control_out.address <= state.address; control_out.seq_mem_access_count <= state.seq_mem_access_count; control_out.ready <= state.ready; - control_out.is_write <= state.is_write; + control_out.instruction <= state.instruction; end process comb_proc; sync_proc: process(clk, state) @@ -49,14 +50,14 @@ begin (others => '0'), (others => '0'), '1', - '0'); + x"00"); else state.ready <= not ored; if ored = '0' then state.address <= control_in.address; state.seq_mem_access_count <= control_in.seq_mem_access_count; state.curr_driver <= control_in.driver_id; - state.is_write <= control_in.is_write; + state.instruction <= control_in.instruction; end if; end if; end if; diff --git a/src/control_unit_tb.vhd b/src/control_unit_tb.vhd index 3921f52..62eefd8 100644 --- a/src/control_unit_tb.vhd +++ b/src/control_unit_tb.vhd @@ -18,13 +18,13 @@ architecture tb of control_unit_tb is (others => '0'), (others => '0'), (others => '0'), - '0'); + x"00"); signal control_output: control_unit_out_t := ( (others => '0'), (others => '0'), (others => '1'), '1', - '0'); + x"00"); signal current_driver : std_logic_vector(2 downto 0) := "000"; shared variable word_counter: natural := 0; @@ -55,7 +55,7 @@ begin control_input.active_driver <= "000"; control_input.address <= x"F0F0F0F0"; control_input.seq_mem_access_count <= "00000011"; - control_input.is_write <= '1'; + control_input.instruction <= x"81"; word_counter := 3; wait for cycle; current_driver <= "010"; @@ -79,7 +79,7 @@ begin wait for cycle; assert control_output.driver_id = "010" report "Incorrect driver_id from control_unit" severity error; assert control_output.address = x"F0F0F0F0" report "Incorrect address from control_unit" severity error; - assert control_output.is_write = '0' report "Incorrect memory op from control_unit" severity error; + assert control_output.instruction = x"81" report "Incorrect memory op from control_unit" severity error; wait for 5 * cycle; reset <= '1'; diff --git a/src/io_type_pkg.vhd b/src/io_type_pkg.vhd index ea50409..6238419 100644 --- a/src/io_type_pkg.vhd +++ b/src/io_type_pkg.vhd @@ -18,19 +18,21 @@ package io_types is constant number_of_drivers: natural := 3; constant address_width: natural := 32; constant seq_vector_length: natural := 8; + constant inst_word_width: natural := 8; type control_unit_out_t is record driver_id: std_logic_vector(number_of_drivers - 1 downto 0); address: std_logic_vector(address_width - 1 downto 0); seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); - ready, is_write: std_logic; + ready: std_logic; + instruction: std_logic_vector(inst_word_width - 1 downto 0); end record control_unit_out_t; type control_unit_in_t is record driver_id, active_driver: std_logic_vector(number_of_drivers - 1 downto 0); address: std_logic_vector(address_width - 1 downto 0); seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); - is_write: std_logic; + instruction: std_logic_vector(inst_word_width - 1 downto 0); end record control_unit_in_t; --- PROTOCOL INFORMATION --- constant interface_inst : interface_inst_t := ( From 0ebc9bec9b87280babfede129e3a809f8f737ecb Mon Sep 17 00:00:00 2001 From: Adam Magnusson Date: Wed, 5 Mar 2025 17:02:07 +0100 Subject: [PATCH 26/40] Adjusted io types for communication between control unit and driver. Also started testbench --- src/control_socbridge_tb.vhd | 24 ++++++++++++++++ src/control_unit.vhd | 28 ++++++++++--------- src/io_type_pkg.vhd | 53 +++++++++++++++++++++--------------- 3 files changed, 70 insertions(+), 35 deletions(-) create mode 100644 src/control_socbridge_tb.vhd diff --git a/src/control_socbridge_tb.vhd b/src/control_socbridge_tb.vhd new file mode 100644 index 0000000..bd7fec5 --- /dev/null +++ b/src/control_socbridge_tb.vhd @@ -0,0 +1,24 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.NUMERIC_STD.all; +library work; +use work.io_types.all; +use work.socbridge_driver_tb_pkg.all; + +entity control_socbridge_tb is +end entity control_socbridge_tb; + +architecture tb of control_socbridge_tb is + +begin + + clock_proc: process + begin + for i in 0 to 50 loop + wait for cycle / 2; + clock <= not clock; + end loop; + wait; + end process clock_proc; + +end architecture tb; diff --git a/src/control_unit.vhd b/src/control_unit.vhd index 7c4095b..f3a8a25 100644 --- a/src/control_unit.vhd +++ b/src/control_unit.vhd @@ -7,9 +7,11 @@ use work.io_types.all; entity control_unit is port ( - clk, rst: in std_logic; - control_in: in control_unit_in_t; - control_out: out control_unit_out_t + clk, rst : in std_logic; + ext_control_in : in ext_control_unit_in_t; + ext_control_out : out ext_control_unit_out_t; + int_control_in : in int_control_unit_in_t; + int_control_out : out int_control_unit_out_t; ); end entity control_unit; @@ -33,13 +35,13 @@ begin begin ored := '0'; ready_reduction: for i in 0 to number_of_drivers - 1 loop - ored := ored or control_in.active_driver(i); + ored := ored or int_control_in.active_driver(i); end loop ready_reduction; - control_out.driver_id <= state.curr_driver; - control_out.address <= state.address; - control_out.seq_mem_access_count <= state.seq_mem_access_count; - control_out.ready <= state.ready; - control_out.instruction <= state.instruction; + int_control_out.driver_id <= state.curr_driver; + int_control_out.address <= state.address; + int_control_out.seq_mem_access_count <= state.seq_mem_access_count; + int_control_out.ready <= state.ready; + int_control_out.instruction <= state.instruction; end process comb_proc; sync_proc: process(clk, state) @@ -54,10 +56,10 @@ begin else state.ready <= not ored; if ored = '0' then - state.address <= control_in.address; - state.seq_mem_access_count <= control_in.seq_mem_access_count; - state.curr_driver <= control_in.driver_id; - state.instruction <= control_in.instruction; + state.address <= ext_control_in.address; + state.seq_mem_access_count <= ext_control_in.seq_mem_access_count; + state.curr_driver <= ext_control_in.driver_id; + state.instruction <= ext_control_in.instruction; end if; end if; end if; diff --git a/src/io_type_pkg.vhd b/src/io_type_pkg.vhd index 6238419..a3f3ca1 100644 --- a/src/io_type_pkg.vhd +++ b/src/io_type_pkg.vhd @@ -3,6 +3,12 @@ use IEEE.std_logic_1164.all; use IEEE.MATH_REAL.all; package io_types is + + --- CONSTANTS --- + constant number_of_drivers: natural := 3; + constant address_width: natural := 32; + constant seq_vector_length: natural := 8; + constant inst_word_width: natural := 8; --- STANDARD TYPES --- type ext_protocol_def_t is record @@ -15,25 +21,28 @@ package io_types is socbridge: ext_protocol_def_t; end record interface_inst_t; - constant number_of_drivers: natural := 3; - constant address_width: natural := 32; - constant seq_vector_length: natural := 8; - constant inst_word_width: natural := 8; - - type control_unit_out_t is record + type ext_control_unit_in_t is record driver_id: std_logic_vector(number_of_drivers - 1 downto 0); address: std_logic_vector(address_width - 1 downto 0); seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); - ready: std_logic; - instruction: std_logic_vector(inst_word_width - 1 downto 0); - end record control_unit_out_t; - - type control_unit_in_t is record - driver_id, active_driver: std_logic_vector(number_of_drivers - 1 downto 0); - address: std_logic_vector(address_width - 1 downto 0); - seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); instruction: std_logic_vector(inst_word_width - 1 downto 0); end record control_unit_in_t; + + type ext_control_unit_out_t is record + ready: std_logic; + end record ext_control_unit_out_t; + + type int_control_unit_out_t is record + driver_id: std_logic_vector(number_of_drivers - 1 downto 0); + address: std_logic_vector(address_width - 1 downto 0); + seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); + instruction: std_logic_vector(inst_word_width - 1 downto 0); + end record control_unit_out_t; + + type int_control_unit_in_t is record + active_driver: std_logic_vector(number_of_drivers - 1 downto 0) + end record int_control_unit_out_t; + --- PROTOCOL INFORMATION --- constant interface_inst : interface_inst_t := ( socbridge => ("SoCBridge ", 8, 2, 2) @@ -41,23 +50,23 @@ package io_types is --- AUTOGENERATED TYPES --- type ext_socbridge_in_t is record - payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); - control : STD_LOGIC_VECTOR(interface_inst.socbridge.control_width_in - 1 downto 0); + payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); + control : STD_LOGIC_VECTOR(interface_inst.socbridge.control_width_in - 1 downto 0); end record ext_socbridge_in_t; type ext_socbridge_out_t is record - payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); - control : STD_LOGIC_VECTOR(interface_inst.socbridge.control_width_in - 1 downto 0); + payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); + control : STD_LOGIC_VECTOR(interface_inst.socbridge.control_width_in - 1 downto 0); end record ext_socbridge_out_t; type int_socbridge_in_t is record - payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); - write_enable_in, is_full_out : std_logic; + payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); + write_enable_in, is_full_out : std_logic; end record int_socbridge_in_t; type int_socbridge_out_t is record - payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); - write_enable_out, is_full_in : std_logic; + payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); + write_enable_out, is_full_in : std_logic; end record int_socbridge_out_t; type ext_interface_in_t is record From cd2c920c48d9cc014a33b33ff26a2d4c3b6e8403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Thu, 6 Mar 2025 14:25:22 +0100 Subject: [PATCH 27/40] remodeled entire project to use VHDL libraries --- .gitignore | 4 +- src/{ => controller}/control_unit.vhd | 10 ++-- src/{ => controller}/control_unit_tb.vhd | 49 +++++++++---------- src/{ => ganimede}/control_socbridge_tb.vhd | 3 +- src/{ => ganimede}/ganimede.vhd | 0 src/{ => ganimede}/io_type_pkg.vhd | 10 ++-- src/{ => socbridge}/socbridge_driver.vhd | 3 +- src/{ => socbridge}/socbridge_driver_tb.gtkw | 0 src/{ => socbridge}/socbridge_driver_tb.vhd | 3 +- .../socbridge_driver_tb_pkg.vhd | 4 +- src/test.vhd | 27 ---------- 11 files changed, 44 insertions(+), 69 deletions(-) rename src/{ => controller}/control_unit.vhd (90%) rename src/{ => controller}/control_unit_tb.vhd (53%) rename src/{ => ganimede}/control_socbridge_tb.vhd (89%) rename src/{ => ganimede}/ganimede.vhd (100%) rename src/{ => ganimede}/io_type_pkg.vhd (96%) rename src/{ => socbridge}/socbridge_driver.vhd (99%) rename src/{ => socbridge}/socbridge_driver_tb.gtkw (100%) rename src/{ => socbridge}/socbridge_driver_tb.vhd (99%) rename src/{ => socbridge}/socbridge_driver_tb_pkg.vhd (98%) delete mode 100644 src/test.vhd diff --git a/.gitignore b/.gitignore index 0be0f35..aaae97c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -*/wave -*/work +**/wave +**/work diff --git a/src/control_unit.vhd b/src/controller/control_unit.vhd similarity index 90% rename from src/control_unit.vhd rename to src/controller/control_unit.vhd index f3a8a25..c013767 100644 --- a/src/control_unit.vhd +++ b/src/controller/control_unit.vhd @@ -1,8 +1,8 @@ library IEEE; use IEEE.std_logic_1164.all; use IEEE.MATH_REAL.all; -library work; -use work.io_types.all; +library ganimede; +use ganimede.io_types.all; entity control_unit is @@ -11,7 +11,7 @@ entity control_unit is ext_control_in : in ext_control_unit_in_t; ext_control_out : out ext_control_unit_out_t; int_control_in : in int_control_unit_in_t; - int_control_out : out int_control_unit_out_t; + int_control_out : out int_control_unit_out_t ); end entity control_unit; @@ -31,7 +31,7 @@ architecture behave of control_unit is begin - comb_proc: process(control_in, state) + comb_proc: process(ext_control_in, int_control_in, state) begin ored := '0'; ready_reduction: for i in 0 to number_of_drivers - 1 loop @@ -40,7 +40,7 @@ begin int_control_out.driver_id <= state.curr_driver; int_control_out.address <= state.address; int_control_out.seq_mem_access_count <= state.seq_mem_access_count; - int_control_out.ready <= state.ready; + ext_control_out.ready <= state.ready; int_control_out.instruction <= state.instruction; end process comb_proc; diff --git a/src/control_unit_tb.vhd b/src/controller/control_unit_tb.vhd similarity index 53% rename from src/control_unit_tb.vhd rename to src/controller/control_unit_tb.vhd index 62eefd8..db8b317 100644 --- a/src/control_unit_tb.vhd +++ b/src/controller/control_unit_tb.vhd @@ -1,9 +1,10 @@ library IEEE; use IEEE.std_logic_1164.all; use IEEE.MATH_REAL.all; -use ieee.numeric_std.all; -library work; -use work.io_types.all; +use IEEE.numeric_std.all; +library ganimede; +use ganimede.io_types.all; +library controller; entity control_unit_tb is end entity control_unit_tb; @@ -13,18 +14,14 @@ architecture tb of control_unit_tb is constant cycle: Time := 10 ns; signal clock: std_logic := '0'; signal reset: std_logic := '0'; - signal control_input: control_unit_in_t := ( - (others => '0'), + signal ext_control_input: ext_control_unit_in_t := ( (others => '0'), (others => '0'), (others => '0'), x"00"); - signal control_output: control_unit_out_t := ( - (others => '0'), - (others => '0'), - (others => '1'), - '1', - x"00"); + signal int_control_input: int_control_unit_in_t := (active_driver => (others => '0')); + signal ext_control_output: ext_control_unit_out_t; + signal int_control_output: int_control_unit_out_t; signal current_driver : std_logic_vector(2 downto 0) := "000"; shared variable word_counter: natural := 0; @@ -39,23 +36,25 @@ begin wait; end process clock_proc; - control_unit_inst: entity work.control_unit + control_unit_inst: entity controller.control_unit port map( - clk => clock, - rst => reset, - control_in => control_input, - control_out => control_output + clk => clock, + rst => reset, + ext_control_in => ext_control_input, + ext_control_out => ext_control_output, + int_control_in => int_control_input, + int_control_out => int_control_output ); stimulus_proc: process begin wait for cycle; - control_input.driver_id <= "010"; - control_input.active_driver <= "000"; - control_input.address <= x"F0F0F0F0"; - control_input.seq_mem_access_count <= "00000011"; - control_input.instruction <= x"81"; + ext_control_input.driver_id <= "010"; + int_control_input.active_driver <= "000"; + ext_control_input.address <= x"F0F0F0F0"; + ext_control_input.seq_mem_access_count <= "00000011"; + ext_control_input.instruction <= x"81"; word_counter := 3; wait for cycle; current_driver <= "010"; @@ -66,7 +65,7 @@ begin report "words remaining are " & integer'image(i); end loop for_loop; - control_input.active_driver <= "000"; + int_control_input.active_driver <= "000"; report "Stim process done"; wait; end process stimulus_proc; @@ -77,9 +76,9 @@ begin wait for cycle; wait for cycle; - assert control_output.driver_id = "010" report "Incorrect driver_id from control_unit" severity error; - assert control_output.address = x"F0F0F0F0" report "Incorrect address from control_unit" severity error; - assert control_output.instruction = x"81" report "Incorrect memory op from control_unit" severity error; + assert int_control_output.driver_id = "010" report "Incorrect driver_id from control_unit" severity error; + assert int_control_output.address = x"F0F0F0F0" report "Incorrect address from control_unit" severity error; + assert int_control_output.instruction = x"81" report "Incorrect memory op from control_unit" severity error; wait for 5 * cycle; reset <= '1'; diff --git a/src/control_socbridge_tb.vhd b/src/ganimede/control_socbridge_tb.vhd similarity index 89% rename from src/control_socbridge_tb.vhd rename to src/ganimede/control_socbridge_tb.vhd index bd7fec5..10d2985 100644 --- a/src/control_socbridge_tb.vhd +++ b/src/ganimede/control_socbridge_tb.vhd @@ -3,7 +3,8 @@ use IEEE.std_logic_1164.all; use IEEE.NUMERIC_STD.all; library work; use work.io_types.all; -use work.socbridge_driver_tb_pkg.all; +library socbridge; +use socbridge.tb_pkg.all; entity control_socbridge_tb is end entity control_socbridge_tb; diff --git a/src/ganimede.vhd b/src/ganimede/ganimede.vhd similarity index 100% rename from src/ganimede.vhd rename to src/ganimede/ganimede.vhd diff --git a/src/io_type_pkg.vhd b/src/ganimede/io_type_pkg.vhd similarity index 96% rename from src/io_type_pkg.vhd rename to src/ganimede/io_type_pkg.vhd index a3f3ca1..963e284 100644 --- a/src/io_type_pkg.vhd +++ b/src/ganimede/io_type_pkg.vhd @@ -21,12 +21,12 @@ package io_types is socbridge: ext_protocol_def_t; end record interface_inst_t; - type ext_control_unit_in_t is record + type ext_control_unit_in_t is record driver_id: std_logic_vector(number_of_drivers - 1 downto 0); address: std_logic_vector(address_width - 1 downto 0); seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); instruction: std_logic_vector(inst_word_width - 1 downto 0); - end record control_unit_in_t; + end record ext_control_unit_in_t; type ext_control_unit_out_t is record ready: std_logic; @@ -37,11 +37,11 @@ package io_types is address: std_logic_vector(address_width - 1 downto 0); seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); instruction: std_logic_vector(inst_word_width - 1 downto 0); - end record control_unit_out_t; + end record int_control_unit_out_t; type int_control_unit_in_t is record - active_driver: std_logic_vector(number_of_drivers - 1 downto 0) - end record int_control_unit_out_t; + active_driver: std_logic_vector(number_of_drivers - 1 downto 0); + end record int_control_unit_in_t; --- PROTOCOL INFORMATION --- constant interface_inst : interface_inst_t := ( diff --git a/src/socbridge_driver.vhd b/src/socbridge/socbridge_driver.vhd similarity index 99% rename from src/socbridge_driver.vhd rename to src/socbridge/socbridge_driver.vhd index 9261c85..c2c393f 100644 --- a/src/socbridge_driver.vhd +++ b/src/socbridge/socbridge_driver.vhd @@ -2,8 +2,9 @@ library IEEE; use IEEE.std_logic_1164.all; use IEEE.NUMERIC_STD.all; library work; -use work.io_types.all; use work.socbridge_driver_tb_pkg.all; +library ganimede; +use ganimede.io_types.all; entity socbridge_driver is diff --git a/src/socbridge_driver_tb.gtkw b/src/socbridge/socbridge_driver_tb.gtkw similarity index 100% rename from src/socbridge_driver_tb.gtkw rename to src/socbridge/socbridge_driver_tb.gtkw diff --git a/src/socbridge_driver_tb.vhd b/src/socbridge/socbridge_driver_tb.vhd similarity index 99% rename from src/socbridge_driver_tb.vhd rename to src/socbridge/socbridge_driver_tb.vhd index ae74ab4..104a2ad 100644 --- a/src/socbridge_driver_tb.vhd +++ b/src/socbridge/socbridge_driver_tb.vhd @@ -2,8 +2,9 @@ library IEEE; use IEEE.std_logic_1164.all; use IEEE.MATH_REAL.all; library work; -use work.io_types.all; use work.socbridge_driver_tb_pkg.all; +library ganimede; +use ganimede.io_types.all; entity socbridge_driver_tb is diff --git a/src/socbridge_driver_tb_pkg.vhd b/src/socbridge/socbridge_driver_tb_pkg.vhd similarity index 98% rename from src/socbridge_driver_tb_pkg.vhd rename to src/socbridge/socbridge_driver_tb_pkg.vhd index 11acdf6..14b5d11 100644 --- a/src/socbridge_driver_tb_pkg.vhd +++ b/src/socbridge/socbridge_driver_tb_pkg.vhd @@ -2,8 +2,8 @@ library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use IEEE.MATH_REAL.all; -library work; -use work.io_types.all; +library ganimede; +use ganimede.io_types.all; package socbridge_driver_tb_pkg is diff --git a/src/test.vhd b/src/test.vhd deleted file mode 100644 index 5a27d24..0000000 --- a/src/test.vhd +++ /dev/null @@ -1,27 +0,0 @@ -library IEEE; -library work; -use work.io_types.all; - -entity test is - port ( - ext_interface_in : in ext_interface_in_t; - ext_interface_out : out ext_interface_out_t - ); -end entity test; - -architecture rtl of test is - signal int_interface_in : int_interface_in_t; - signal int_interface_out : int_interface_out_t; -begin - - proc_name: process - begin - - report "Hello"; - report integer'image(ext_interface_in.socbridge.payload'length); - report integer'image(ext_interface_in.spi.payload'length); - wait; - end process proc_name; - - -end architecture rtl; From 6baa2fd002c1f402b27504aaf9274b2b3b13c23e Mon Sep 17 00:00:00 2001 From: Adam Magnusson Date: Thu, 6 Mar 2025 15:24:37 +0100 Subject: [PATCH 28/40] Gantry include paths are now relative --- scripts/build_env.py | 12 ++++-------- scripts/elab.py | 4 ++-- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/scripts/build_env.py b/scripts/build_env.py index b6fceff..d9ff493 100644 --- a/scripts/build_env.py +++ b/scripts/build_env.py @@ -43,20 +43,16 @@ def addAllVHDLFiles(std: str, lib: str, init=False): return -1 vhdlFiles = [] currentlyAdded = [] - absWorkDir = os.path.join(os.getcwd(), "work") cfFileId = getCfFileId(std) ## Find already present files if not init: - cfFileName = list(filter(lambda x: ".cf" in x and lib in x and cfFileId in x, os.listdir(absWorkDir)))[0] - cfFilePath = os.path.join(absWorkDir,cfFileName) + cfFileName = list(filter(lambda x: ".cf" in x and lib in x and cfFileId in x, os.listdir("work")))[0] + cfFilePath = os.path.join("work",cfFileName) currentlyAdded = getCurrentlyAddedFiles(cfFilePath) - print(currentlyAdded) ## Add files not added for file in os.listdir(): - print(file) - print(currentlyAdded, file, file not in currentlyAdded) if ".vhd" in file and file not in currentlyAdded: - vhdlFiles.append(os.path.join(os.getcwd(), file)) + vhdlFiles.append(file) if len(vhdlFiles) > 0: print(f"Detected new files. Adding {vhdlFiles}") command = ["ghdl", "-i", "--workdir=work", f"--work={lib}", f"--std={std}"] + vhdlFiles @@ -68,5 +64,5 @@ def getCurrentlyAddedFiles(cfFilePath:str): lines = f.readlines() f.close() fileLines = filter(lambda x: "file" in x, lines) - files = map(lambda x: split("\"",x)[1], fileLines) + files = map(lambda x: split("\" \"",x)[1], fileLines) return list(files) diff --git a/scripts/elab.py b/scripts/elab.py index 1d5a040..7cf0edc 100644 --- a/scripts/elab.py +++ b/scripts/elab.py @@ -7,7 +7,7 @@ from typing import List def generateIncludesForGHDL(includes: List[str]): cmd = [] for inc in includes: - cmd.append(f"-P{os.path.join(os.getcwd(), f"{inc}/work")}") + cmd.append(f"-P{inc}/work") return cmd def elabDesign(topDef: str, arch: str, lib: str, std: str, includes: List[str]): @@ -26,7 +26,7 @@ def runDesign(topDef: str, arch: str, lib: str, std: str, includes): print("Elaboration failed...") return -1 os.makedirs("wave",exist_ok=True) - wavePath = os.path.join(os.getcwd(), "wave") + wavePath = "wave" incs = generateIncludesForGHDL(includes) command = [ ## may add -v for verbose "ghdl", "--elab-run", f"--workdir=work", f"--work={lib}", f"--std={std}"] + incs + ["-o", f"work/{topDef}-{arch}", f"{topDef}", f"{arch}", From a9f1e0fb377c0edc813dafc0fbfdeb9186594047 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Thu, 6 Mar 2025 15:38:20 +0100 Subject: [PATCH 29/40] vhdl_ls configuration --- src/vhdl_ls.toml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/vhdl_ls.toml diff --git a/src/vhdl_ls.toml b/src/vhdl_ls.toml new file mode 100644 index 0000000..b7085cb --- /dev/null +++ b/src/vhdl_ls.toml @@ -0,0 +1,18 @@ +# What standard to use. This is optional and defaults to VHDL2008. +standard = "1993" +# File names are either absolute or relative to the parent folder of the vhdl_ls.toml file +[libraries] +ganimede.files = [ + 'ganimede/*.vhd' +] +socbridge.files = [ + 'socbridge/*.vhd' +] + +controller.files = [ + 'controller/*.vhd', +] + +[lint] +unused = 'error' # Upgrade the 'unused' diagnostic to the 'error' severity +unnecessary_work_library = false # Disable linting for the 'library work;' statement From ad3314bb259708210f0a0dc4092d7dee54121d3a Mon Sep 17 00:00:00 2001 From: Adam Magnusson Date: Fri, 7 Mar 2025 10:42:13 +0100 Subject: [PATCH 30/40] Boilerplate for control unit and socbridge driver testbench --- src/ganimede/control_socbridge_tb.vhd | 67 +++++++++++++++++++++++++-- src/ganimede/io_type_pkg.vhd | 1 + src/socbridge/socbridge_driver_tb.vhd | 27 +++++------ 3 files changed, 79 insertions(+), 16 deletions(-) diff --git a/src/ganimede/control_socbridge_tb.vhd b/src/ganimede/control_socbridge_tb.vhd index 10d2985..e961672 100644 --- a/src/ganimede/control_socbridge_tb.vhd +++ b/src/ganimede/control_socbridge_tb.vhd @@ -4,22 +4,83 @@ use IEEE.NUMERIC_STD.all; library work; use work.io_types.all; library socbridge; -use socbridge.tb_pkg.all; +use socbridge.socbridge_driver_tb_pkg.all; +library controller; entity control_socbridge_tb is end entity control_socbridge_tb; architecture tb of control_socbridge_tb is - + + constant cycle : Time := 10 ns; + signal clk, rst : std_logic; + signal cu_to_sb_cmd: command_t; + signal cu_to_sb_address: std_logic_vector(31 downto 0); + signal cmd_size : positive; + signal ext_socbridge_in : ext_socbridge_in_t := ( + payload => (others => '0'), + control => (others => '0') + ); + signal ext_socbridge_out : ext_socbridge_out_t; + signal int_socbridge_in : int_socbridge_in_t; + signal int_socbridge_out : int_socbridge_out_t := ( + payload => (others => '0'), + write_enable_out => '0', + is_full_in => '0' + ); + signal ext_control_input: ext_control_unit_in_t := ( + driver_id => (others => '0'), + address => (others => '0'), + seq_mem_access_count => (others => '0'), + instruction => x"00" + ); + signal int_control_input: int_control_unit_in_t := (active_driver => (others => '0')); + signal ext_control_output: ext_control_unit_out_t; + signal int_control_output: int_control_unit_out_t; begin + + + socbridge_inst: entity socbridge.socbridge_driver + port map( + clk => clk, + rst => rst, + cmd => cu_to_sb_cmd, + address => cu_to_sb_address, + cmd_size => cmd_size, + ext_in => ext_socbridge_in, + ext_out => ext_socbridge_out, + int_in => int_socbridge_in, + int_out => int_socbridge_out + ); + + control_unit_inst: entity controller.control_unit + port map( + clk => clk, + rst => rst, + ext_control_in => ext_control_input, + ext_control_out => ext_control_output, + int_control_in => int_control_input, + int_control_out => int_control_output + ); + clock_proc: process begin for i in 0 to 50 loop wait for cycle / 2; - clock <= not clock; + clk <= not clk; end loop; wait; end process clock_proc; + stimulus_proc: process + begin + + end process stimulus_proc; + + monitor_proc: process + begin + + end process monitor_proc; + end architecture tb; diff --git a/src/ganimede/io_type_pkg.vhd b/src/ganimede/io_type_pkg.vhd index 963e284..32e351d 100644 --- a/src/ganimede/io_type_pkg.vhd +++ b/src/ganimede/io_type_pkg.vhd @@ -21,6 +21,7 @@ package io_types is socbridge: ext_protocol_def_t; end record interface_inst_t; + --- CONTROL UNIT --- type ext_control_unit_in_t is record driver_id: std_logic_vector(number_of_drivers - 1 downto 0); address: std_logic_vector(address_width - 1 downto 0); diff --git a/src/socbridge/socbridge_driver_tb.vhd b/src/socbridge/socbridge_driver_tb.vhd index 104a2ad..057b57a 100644 --- a/src/socbridge/socbridge_driver_tb.vhd +++ b/src/socbridge/socbridge_driver_tb.vhd @@ -5,6 +5,7 @@ library work; use work.socbridge_driver_tb_pkg.all; library ganimede; use ganimede.io_types.all; +library socbridge; entity socbridge_driver_tb is @@ -59,19 +60,19 @@ architecture tb of socbridge_driver_tb is end if; end procedure; - component socbridge_driver is - port( - clk : in std_logic; - rst : in std_logic; - cmd : in command_t; - address : in std_logic_vector(31 downto 0); - cmd_size: in positive; - ext_in : in ext_socbridge_in_t; - ext_out : out ext_socbridge_out_t; - int_in : out int_socbridge_in_t; - int_out : in int_socbridge_out_t - ); - end component socbridge_driver; +-- component socbridge_driver is +-- port( +-- clk : in std_logic; +-- rst : in std_logic; +-- cmd : in command_t; +-- address : in std_logic_vector(31 downto 0); +-- cmd_size: in positive; +-- ext_in : in ext_socbridge_in_t; +-- ext_out : out ext_socbridge_out_t; +-- int_in : out int_socbridge_in_t; +-- int_out : in int_socbridge_out_t +-- ); +-- end component socbridge_driver; begin socbridge_driver_inst: entity work.socbridge_driver From 10da15a2e39e38e3b60a0fa02b1ffbccf3b63a13 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 7 Mar 2025 16:58:08 +0100 Subject: [PATCH 31/40] Fixed typing and added translator module to driver (facilitate multi message action) YES --- src/controller/control_unit.vhd | 13 +- src/controller/control_unit_tb.vhd | 10 +- src/ganimede/control_socbridge_tb.vhd | 33 ++-- src/ganimede/io_type_pkg.vhd | 45 ++++-- src/socbridge/socbridge_driver.vhd | 182 ++++++++++++++++------ src/socbridge/socbridge_driver_tb.vhd | 2 +- src/socbridge/socbridge_driver_tb_pkg.vhd | 14 +- src/vhdl_ls.toml | 2 +- 8 files changed, 211 insertions(+), 90 deletions(-) diff --git a/src/controller/control_unit.vhd b/src/controller/control_unit.vhd index c013767..00a4f5d 100644 --- a/src/controller/control_unit.vhd +++ b/src/controller/control_unit.vhd @@ -19,10 +19,10 @@ end entity control_unit; architecture behave of control_unit is type state_t is record address: std_logic_vector(address_width - 1 downto 0); - seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); + seq_mem_access_count: integer; curr_driver: std_logic_vector(number_of_drivers - 1 downto 0); --one-hot encoded, 0 means disabled ready: std_logic; - instruction: std_logic_vector(inst_word_width - 1 downto 0); + instruction: instruction_command_t; end record state_t; signal state: state_t; @@ -49,17 +49,20 @@ begin if rising_edge(clk) then if rst = '1' then state <= ((others => '0'), - (others => '0'), + 0, (others => '0'), '1', - x"00"); + NO_OP); else state.ready <= not ored; if ored = '0' then state.address <= ext_control_in.address; state.seq_mem_access_count <= ext_control_in.seq_mem_access_count; state.curr_driver <= ext_control_in.driver_id; - state.instruction <= ext_control_in.instruction; + with ext_control_in.cmd select + state.instruction <= WRITE when "01", + READ when "10", + NO_OP when others; end if; end if; end if; diff --git a/src/controller/control_unit_tb.vhd b/src/controller/control_unit_tb.vhd index db8b317..3fb4e22 100644 --- a/src/controller/control_unit_tb.vhd +++ b/src/controller/control_unit_tb.vhd @@ -17,8 +17,8 @@ architecture tb of control_unit_tb is signal ext_control_input: ext_control_unit_in_t := ( (others => '0'), (others => '0'), - (others => '0'), - x"00"); + 0, + "00"); signal int_control_input: int_control_unit_in_t := (active_driver => (others => '0')); signal ext_control_output: ext_control_unit_out_t; signal int_control_output: int_control_unit_out_t; @@ -53,8 +53,8 @@ begin ext_control_input.driver_id <= "010"; int_control_input.active_driver <= "000"; ext_control_input.address <= x"F0F0F0F0"; - ext_control_input.seq_mem_access_count <= "00000011"; - ext_control_input.instruction <= x"81"; + ext_control_input.seq_mem_access_count <= 3; + ext_control_input.cmd <= "01"; word_counter := 3; wait for cycle; current_driver <= "010"; @@ -78,7 +78,7 @@ begin wait for cycle; assert int_control_output.driver_id = "010" report "Incorrect driver_id from control_unit" severity error; assert int_control_output.address = x"F0F0F0F0" report "Incorrect address from control_unit" severity error; - assert int_control_output.instruction = x"81" report "Incorrect memory op from control_unit" severity error; + assert int_control_output.instruction = WRITE report "Incorrect memory op from control_unit" severity error; wait for 5 * cycle; reset <= '1'; diff --git a/src/ganimede/control_socbridge_tb.vhd b/src/ganimede/control_socbridge_tb.vhd index e961672..3eed3a4 100644 --- a/src/ganimede/control_socbridge_tb.vhd +++ b/src/ganimede/control_socbridge_tb.vhd @@ -1,8 +1,8 @@ library IEEE; use IEEE.std_logic_1164.all; use IEEE.NUMERIC_STD.all; -library work; -use work.io_types.all; +library ganimede; +use ganimede.io_types.all; library socbridge; use socbridge.socbridge_driver_tb_pkg.all; library controller; @@ -22,8 +22,8 @@ architecture tb of control_socbridge_tb is control => (others => '0') ); signal ext_socbridge_out : ext_socbridge_out_t; - signal int_socbridge_in : int_socbridge_in_t; - signal int_socbridge_out : int_socbridge_out_t := ( + signal int_socbridge_out : int_socbridge_out_t; + signal int_socbridge_in : int_socbridge_in_t := ( payload => (others => '0'), write_enable_out => '0', is_full_in => '0' @@ -31,26 +31,26 @@ architecture tb of control_socbridge_tb is signal ext_control_input: ext_control_unit_in_t := ( driver_id => (others => '0'), address => (others => '0'), - seq_mem_access_count => (others => '0'), - instruction => x"00" + seq_mem_access_count => 0, + cmd => x"00" ); signal int_control_input: int_control_unit_in_t := (active_driver => (others => '0')); signal ext_control_output: ext_control_unit_out_t; signal int_control_output: int_control_unit_out_t; -begin - + signal driver_to_control: driver_to_control_t; + signal control_to_driver: control_to_driver_t; +begin socbridge_inst: entity socbridge.socbridge_driver port map( clk => clk, rst => rst, - cmd => cu_to_sb_cmd, - address => cu_to_sb_address, - cmd_size => cmd_size, - ext_in => ext_socbridge_in, + ctrl_in => control_to_driver, + ctrl_out => driver_to_control, + ext_in => ext_socbridge_in, ext_out => ext_socbridge_out, - int_in => int_socbridge_in, + int_in => int_socbridge_in, int_out => int_socbridge_out ); @@ -63,6 +63,13 @@ begin int_control_in => int_control_input, int_control_out => int_control_output ); + + control_to_driver.address <= int_control_output.address; + control_to_driver.request <= int_control_output.driver_id(0); + control_to_driver.instruction <= int_control_output.instruction; + control_to_driver.seq_mem_access_count <= int_control_output.seq_mem_access_count; + + int_control_input.active_driver(0) <= driver_to_control.is_active; clock_proc: process begin diff --git a/src/ganimede/io_type_pkg.vhd b/src/ganimede/io_type_pkg.vhd index 32e351d..a20221b 100644 --- a/src/ganimede/io_type_pkg.vhd +++ b/src/ganimede/io_type_pkg.vhd @@ -5,12 +5,14 @@ use IEEE.MATH_REAL.all; package io_types is --- CONSTANTS --- - constant number_of_drivers: natural := 3; + constant number_of_drivers: natural := 1; constant address_width: natural := 32; constant seq_vector_length: natural := 8; - constant inst_word_width: natural := 8; + constant inst_word_width: natural := 2; --- STANDARD TYPES --- + type instruction_command_t is (NO_OP, READ, WRITE); + type ext_protocol_def_t is record name: string (1 to 20); payload_width: natural; @@ -25,8 +27,8 @@ package io_types is type ext_control_unit_in_t is record driver_id: std_logic_vector(number_of_drivers - 1 downto 0); address: std_logic_vector(address_width - 1 downto 0); - seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); - instruction: std_logic_vector(inst_word_width - 1 downto 0); + seq_mem_access_count: integer; + cmd: std_logic_vector(inst_word_width - 1 downto 0); end record ext_control_unit_in_t; type ext_control_unit_out_t is record @@ -36,14 +38,25 @@ package io_types is type int_control_unit_out_t is record driver_id: std_logic_vector(number_of_drivers - 1 downto 0); address: std_logic_vector(address_width - 1 downto 0); - seq_mem_access_count: std_logic_vector(seq_vector_length - 1 downto 0); - instruction: std_logic_vector(inst_word_width - 1 downto 0); + seq_mem_access_count: integer; + instruction: instruction_command_t; end record int_control_unit_out_t; type int_control_unit_in_t is record active_driver: std_logic_vector(number_of_drivers - 1 downto 0); end record int_control_unit_in_t; + type driver_to_control_t is record + is_active : std_logic; + end record driver_to_control_t; + + type control_to_driver_t is record + request: std_logic; + address: std_logic_vector(address_width - 1 downto 0); + seq_mem_access_count: integer; + instruction: instruction_command_t; + end record control_to_driver_t; + --- PROTOCOL INFORMATION --- constant interface_inst : interface_inst_t := ( socbridge => ("SoCBridge ", 8, 2, 2) @@ -60,16 +73,16 @@ package io_types is control : STD_LOGIC_VECTOR(interface_inst.socbridge.control_width_in - 1 downto 0); end record ext_socbridge_out_t; - type int_socbridge_in_t is record - payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); - write_enable_in, is_full_out : std_logic; - end record int_socbridge_in_t; - type int_socbridge_out_t is record payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); - write_enable_out, is_full_in : std_logic; + write_enable_in, is_full_out : std_logic; end record int_socbridge_out_t; + type int_socbridge_in_t is record + payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); + write_enable_out, is_full_in : std_logic; + end record int_socbridge_in_t; + type ext_interface_in_t is record socbridge : ext_socbridge_in_t; end record ext_interface_in_t; @@ -78,12 +91,12 @@ package io_types is socbridge : ext_socbridge_out_t; end record ext_interface_out_t; - type int_interface_in_t is record - socbridge : int_socbridge_in_t; - end record int_interface_in_t; - type int_interface_out_t is record socbridge : int_socbridge_out_t; end record int_interface_out_t; + type int_interface_in_t is record + socbridge : int_socbridge_in_t; + end record int_interface_in_t; + end package io_types; diff --git a/src/socbridge/socbridge_driver.vhd b/src/socbridge/socbridge_driver.vhd index c2c393f..fb5bf3c 100644 --- a/src/socbridge/socbridge_driver.vhd +++ b/src/socbridge/socbridge_driver.vhd @@ -1,23 +1,25 @@ library IEEE; use IEEE.std_logic_1164.all; use IEEE.NUMERIC_STD.all; -library work; -use work.socbridge_driver_tb_pkg.all; library ganimede; use ganimede.io_types.all; +library socbridge; +use socbridge.socbridge_driver_tb_pkg.all; entity socbridge_driver is port( clk : in std_logic; rst : in std_logic; - cmd : in command_t; - address : in std_logic_vector(31 downto 0); - cmd_size: in positive; + ctrl_in : in control_to_driver_t; + ctrl_out: out driver_to_control_t; + -- cmd : in command_t; + -- address : in std_logic_vector(31 downto 0); + -- cmd_size: in positive; ext_in : in ext_socbridge_in_t; ext_out : out ext_socbridge_out_t; - int_in : out int_socbridge_in_t; - int_out : in int_socbridge_out_t + int_out : out int_socbridge_out_t; + int_in : in int_socbridge_in_t ); end entity socbridge_driver; @@ -27,11 +29,16 @@ architecture rtl of socbridge_driver is signal ext_in_rec : ext_protocol_t; shared variable ext_out_data_cmd : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); signal test : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); + signal next_cmd : command_t; + signal next_cmd_size : integer; signal next_state : state_t; signal curr_cmd_bits : std_logic_vector(4 downto 0); signal curr_response : response_t; signal curr_response_bits : std_logic_vector(4 downto 0); signal st : state_rec_t; + --- TRANSLATOR --- + signal trans_st : translator_state_rec_t; + signal trans_next_state : translator_state_t; begin --- DEBUG GLOBAL BINDINGS --- -- synthesis translate_off @@ -72,11 +79,13 @@ begin READ_RESPONSE when "01000", READ_RESPONSE when "01100", NO_OP when others; - comb_proc: process(ext_in, int_out, curr_response, st, cmd) + comb_proc: process(ext_in, int_in, curr_response, st, ctrl_in, trans_st) begin -- Outputs ext_out <= create_io_type_out_from_ext_protocol(st.ext_out_reg); - + with trans_st.curr_state select + ctrl_out.is_active <= '0' when IDLE, + '1' when others; --- State Transition Diagram --- -- @@ -119,9 +128,9 @@ begin --- Next State Assignment --- case st.curr_state is when IDLE => - if cmd = WRITE or cmd = WRITE_ADD then + if st.curr_cmd = WRITE or st.curr_cmd = WRITE_ADD then next_state <= TX_HEADER; - elsif cmd = READ or cmd = READ_ADD then + elsif st.curr_cmd = READ or st.curr_cmd = READ_ADD then next_state <= RX_HEADER; else next_state <= IDLE; @@ -129,7 +138,7 @@ begin when TX_HEADER => -- The header only takes one word (cycle) to transmit. -- Continue to body or address directly afterwards. - if st.cmd_reg = WRITE_ADD then + if st.curr_cmd = WRITE_ADD then next_state <= ADDR1; else next_state <= TX_BODY; @@ -151,7 +160,7 @@ begin when RX_HEADER => -- The header only takes one word (cycle) to transmit. -- Continue to awaiting response directly afterwards. - if st.cmd_reg = READ_ADD then + if st.curr_cmd = READ_ADD then next_state <= ADDR1; else next_state <= RX_RESPONSE; @@ -180,7 +189,7 @@ begin when ADDR3 => next_state <= ADDR4; when ADDR4 => - if st.cmd_reg = WRITE or st.cmd_reg = WRITE_ADD then + if st.curr_cmd = WRITE or st.curr_cmd = WRITE_ADD then next_state <= TX_BODY; else next_state <= RX_RESPONSE; @@ -189,50 +198,51 @@ begin --- Combinatorial output based on current state --- ext_out_data_cmd := (others => '0'); - int_in.is_full_out <= '1'; - int_in.write_enable_in <= '0'; - int_in.payload <= (others => '0'); + int_out.is_full_out <= '1'; + int_out.write_enable_in <= '0'; + int_out.payload <= (others => '0'); case st.curr_state is when IDLE => - if cmd = WRITE or cmd = WRITE_ADD then - ext_out_data_cmd := get_cmd_bits(cmd) & get_size_bits(cmd_size); - elsif cmd = READ or cmd = READ_ADD then - ext_out_data_cmd := get_cmd_bits(cmd) & get_size_bits(cmd_size); + if st.curr_cmd = WRITE or st.curr_cmd = WRITE_ADD then + ext_out_data_cmd := get_cmd_bits(st.curr_cmd) & get_size_bits(st.curr_cmd_size); + elsif st.curr_cmd = READ or st.curr_cmd = READ_ADD then + ext_out_data_cmd := get_cmd_bits(st.curr_cmd) & get_size_bits(st.curr_cmd_size); + else end if; when TX_HEADER => - if st.cmd_reg = WRITE_ADD then - ext_out_data_cmd := st.addr_reg(7 downto 0); + if st.curr_cmd = WRITE_ADD then + ext_out_data_cmd := st.curr_addr(7 downto 0); else - ext_out_data_cmd := int_out.payload; - int_in.is_full_out <= '0'; + ext_out_data_cmd := int_in.payload; + int_out.is_full_out <= '0'; end if; when TX_BODY => if st.write_stage > 0 then - int_in.is_full_out <= '0'; - ext_out_data_cmd := int_out.payload; + int_out.is_full_out <= '0'; + ext_out_data_cmd := int_in.payload; else ext_out_data_cmd := (others => '0'); end if; when TX_ACK => when RX_HEADER => - if st.cmd_reg = READ_ADD then - ext_out_data_cmd := st.addr_reg(7 downto 0); + if st.curr_cmd = READ_ADD then + ext_out_data_cmd := st.curr_addr(7 downto 0); end if; when RX_RESPONSE => when RX_BODY_NO_OUT => when RX_BODY => - int_in.payload <= st.ext_in_reg.data; - int_in.write_enable_in <= '1'; + int_out.payload <= st.ext_in_reg.data; + int_out.write_enable_in <= '1'; when ADDR1 => - ext_out_data_cmd := st.addr_reg(15 downto 8); + ext_out_data_cmd := st.curr_addr(15 downto 8); when ADDR2 => - ext_out_data_cmd := st.addr_reg(23 downto 16); + ext_out_data_cmd := st.curr_addr(23 downto 16); when ADDR3 => - ext_out_data_cmd := st.addr_reg(31 downto 24); + ext_out_data_cmd := st.curr_addr(31 downto 24); when ADDR4 => - if st.cmd_reg = WRITE_ADD then - int_in.is_full_out <= '0'; - ext_out_data_cmd := int_out.payload; + if st.curr_cmd = WRITE_ADD then + int_out.is_full_out <= '0'; + ext_out_data_cmd := int_in.payload; end if; end case; next_parity_out <= calc_parity(ext_out_data_cmd); @@ -240,9 +250,65 @@ begin -- synthesis translate_off test <= ext_out_data_cmd; -- synthesis translate_on + --- TRANSLATOR --- + + --- Next state assignment + case trans_st.curr_state is + when IDLE => + if trans_st.curr_inst.request = '1' then + trans_next_state <= SEND; + else + trans_next_state <= IDLE; + end if; + -- Wait for driver to go idle and send next instruction. Then enter AWAIT + when SEND => + if st.curr_state /= IDLE then + trans_next_state <= AWAIT; + else + trans_next_state <= SEND; + end if; + -- Wait for driver to finish current instruction, then reenter SEND + when AWAIT => + if trans_st.curr_inst.seq_mem_access_count <= 0 then + trans_next_state <= IDLE; + elsif st.curr_state = IDLE then + trans_next_state <= SEND; + else + trans_next_state <= AWAIT; + end if; + end case; + + --- Combinatorial output based on state + next_cmd <= NO_OP; + next_cmd_size <= 0; + case trans_st.curr_state is + when IDLE => + when SEND => + if trans_st.is_first_word = '1' then + if trans_st.curr_inst.instruction = READ then + next_cmd <= READ_ADD; + elsif trans_st.curr_inst.instruction = WRITE then + next_cmd <= WRITE_ADD; + end if; + else + if trans_st.curr_inst.instruction = READ then + next_cmd <= READ; + elsif trans_st.curr_inst.instruction = WRITE then + next_cmd <= WRITE; + end if; + end if; + + if trans_st.curr_inst.seq_mem_access_count > 256 then + next_cmd_size <= 256; + else + next_cmd_size <= trans_st.curr_inst.seq_mem_access_count; + end if; + when AWAIT => + end case; + end process comb_proc; -- Process updating internal registers based on primary clock - seq_proc: process(ext_in_rec.clk, rst) + seq_proc: process(ext_in_rec.clk, rst, clk) begin if(rst = '1') then st.ext_in_reg.data <= (others => '0'); @@ -252,8 +318,9 @@ begin st.curr_state <= IDLE; st.write_stage <= 0; st.read_stage <= 0; - st.cmd_reg <= NO_OP; - st.addr_reg <= (others => '0'); + st.curr_cmd <= NO_OP; + st.curr_cmd_size <= 0; + st.curr_addr <= (others => '0'); elsif(rising_edge(ext_in_rec.clk)) then st.ext_in_reg.data <= ext_in_rec.data; @@ -265,19 +332,17 @@ begin st.curr_state <= next_state; case st.curr_state is when IDLE => - if cmd = WRITE or cmd = WRITE_ADD or - cmd = READ or cmd = READ_ADD then - st.addr_reg <= address; - st.cmd_reg <= cmd; - end if; + st.curr_cmd <= next_cmd; + st.curr_cmd_size <= next_cmd_size; + st.curr_addr <= trans_st.curr_inst.address; when TX_HEADER => - st.write_stage <= 2**(cmd_size - 1) - 1; + st.write_stage <= 2**(st.curr_cmd_size - 1) - 1; when TX_BODY => if st.write_stage > 0 then st.write_stage <= st.write_stage - 1; end if; when RX_HEADER => - st.read_stage <= 2**(cmd_size - 1) - 1; + st.read_stage <= 2**(st.curr_cmd_size - 1) - 1; when RX_BODY => if st.read_stage > 0 then st.read_stage <= st.read_stage - 1; @@ -286,6 +351,29 @@ begin end case; end if; + --- TRANSLATOR --- + + if(rst = '1') then + trans_st.curr_state <= IDLE; + trans_st.curr_inst.request <= '0'; + trans_st.curr_inst.address <= (others => '0'); + trans_st.curr_inst.seq_mem_access_count <= 0; + trans_st.curr_inst.instruction <= NO_OP; + trans_st.is_first_word <= '1'; + elsif(rising_edge(clk)) then + trans_st.curr_state <= trans_next_state; + case trans_st.curr_state is + when IDLE => + if ctrl_in.request = '1' then + trans_st.curr_inst <= ctrl_in; + end if; + when SEND => + trans_st.curr_inst.seq_mem_access_count <= trans_st.curr_inst.seq_mem_access_count - 256; + when AWAIT => + trans_st.is_first_word <= '0'; + when others => + end case; + end if; end process seq_proc; diff --git a/src/socbridge/socbridge_driver_tb.vhd b/src/socbridge/socbridge_driver_tb.vhd index 057b57a..25a67fc 100644 --- a/src/socbridge/socbridge_driver_tb.vhd +++ b/src/socbridge/socbridge_driver_tb.vhd @@ -75,7 +75,7 @@ architecture tb of socbridge_driver_tb is -- end component socbridge_driver; begin - socbridge_driver_inst: entity work.socbridge_driver + socbridge_driver_inst: entity socbridge.socbridge_driver port map( clk => clk, rst => rst, diff --git a/src/socbridge/socbridge_driver_tb_pkg.vhd b/src/socbridge/socbridge_driver_tb_pkg.vhd index 14b5d11..060d8e8 100644 --- a/src/socbridge/socbridge_driver_tb_pkg.vhd +++ b/src/socbridge/socbridge_driver_tb_pkg.vhd @@ -20,6 +20,15 @@ package socbridge_driver_tb_pkg is TX_HEADER, TX_BODY, TX_ACK, RX_HEADER, RX_RESPONSE, RX_BODY_NO_OUT, RX_BODY); + --- TRANSLATOR --- + type translator_state_t is (IDLE, SEND, AWAIT); + + type translator_state_rec_t is record + curr_inst : control_to_driver_t; + curr_state : translator_state_t; + is_first_word : std_logic; + end record translator_state_rec_t; + type ext_protocol_t is record data : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); clk : std_logic; @@ -30,8 +39,9 @@ package socbridge_driver_tb_pkg is curr_state: state_t; ext_in_reg, ext_out_reg : ext_protocol_t; write_stage, read_stage : NATURAL; - cmd_reg : command_t; - addr_reg : std_logic_vector(31 downto 0); + curr_cmd : command_t; + curr_cmd_size: integer; + curr_addr : std_logic_vector(31 downto 0); end record state_rec_t; impure function calc_parity( d : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0) diff --git a/src/vhdl_ls.toml b/src/vhdl_ls.toml index b7085cb..3a01a68 100644 --- a/src/vhdl_ls.toml +++ b/src/vhdl_ls.toml @@ -3,7 +3,7 @@ standard = "1993" # File names are either absolute or relative to the parent folder of the vhdl_ls.toml file [libraries] ganimede.files = [ - 'ganimede/*.vhd' + 'ganimede/io_type_pkg.vhd' ] socbridge.files = [ 'socbridge/*.vhd' From 9de69209103a82eb8b96dd6d2dfbb6dd22260642 Mon Sep 17 00:00:00 2001 From: Adam Magnusson Date: Mon, 10 Mar 2025 12:01:15 +0100 Subject: [PATCH 32/40] Added some signal assignments to testbench --- src/ganimede/control_socbridge_tb.vhd | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ganimede/control_socbridge_tb.vhd b/src/ganimede/control_socbridge_tb.vhd index 3eed3a4..0542545 100644 --- a/src/ganimede/control_socbridge_tb.vhd +++ b/src/ganimede/control_socbridge_tb.vhd @@ -82,7 +82,10 @@ begin stimulus_proc: process begin - + ext_control_input.address <= x"FB0FB0FB"; + ext_control_input.cmd <= "01"; + ext_control_input.driver_id <= "1"; + ext_control_input.seq_mem_access_count <= 5; end process stimulus_proc; monitor_proc: process From eb574cf2b883eed3ea7e26d9fb30fbb6f849034e Mon Sep 17 00:00:00 2001 From: Adam Magnusson Date: Mon, 10 Mar 2025 15:08:11 +0100 Subject: [PATCH 33/40] Socbridge and controller testbench progress --- src/controller/control_unit_tb.vhd | 12 +- src/ganimede/control_socbridge_tb.vhd | 413 +++++++++++++++++++++++++- src/ganimede/io_type_pkg.vhd | 2 +- 3 files changed, 411 insertions(+), 16 deletions(-) diff --git a/src/controller/control_unit_tb.vhd b/src/controller/control_unit_tb.vhd index 3fb4e22..bad377e 100644 --- a/src/controller/control_unit_tb.vhd +++ b/src/controller/control_unit_tb.vhd @@ -22,7 +22,7 @@ architecture tb of control_unit_tb is signal int_control_input: int_control_unit_in_t := (active_driver => (others => '0')); signal ext_control_output: ext_control_unit_out_t; signal int_control_output: int_control_unit_out_t; - signal current_driver : std_logic_vector(2 downto 0) := "000"; + signal current_driver : std_logic_vector(0 downto 0) := "0"; shared variable word_counter: natural := 0; begin @@ -50,14 +50,14 @@ stimulus_proc: process begin wait for cycle; - ext_control_input.driver_id <= "010"; - int_control_input.active_driver <= "000"; + ext_control_input.driver_id <= "1"; + int_control_input.active_driver <= "0"; ext_control_input.address <= x"F0F0F0F0"; ext_control_input.seq_mem_access_count <= 3; ext_control_input.cmd <= "01"; word_counter := 3; wait for cycle; - current_driver <= "010"; + current_driver <= "1"; report "entering loop with word_counter" & integer'image(word_counter); for_loop: for i in word_counter - 1 downto 0 loop @@ -65,7 +65,7 @@ begin report "words remaining are " & integer'image(i); end loop for_loop; - int_control_input.active_driver <= "000"; + int_control_input.active_driver <= "0"; report "Stim process done"; wait; end process stimulus_proc; @@ -76,7 +76,7 @@ begin wait for cycle; wait for cycle; - assert int_control_output.driver_id = "010" report "Incorrect driver_id from control_unit" severity error; + assert int_control_output.driver_id = "1" report "Incorrect driver_id from control_unit" severity error; assert int_control_output.address = x"F0F0F0F0" report "Incorrect address from control_unit" severity error; assert int_control_output.instruction = WRITE report "Incorrect memory op from control_unit" severity error; diff --git a/src/ganimede/control_socbridge_tb.vhd b/src/ganimede/control_socbridge_tb.vhd index 0542545..0c46ec0 100644 --- a/src/ganimede/control_socbridge_tb.vhd +++ b/src/ganimede/control_socbridge_tb.vhd @@ -12,7 +12,8 @@ end entity control_socbridge_tb; architecture tb of control_socbridge_tb is - constant cycle : Time := 10 ns; + constant CLK_PERIOD : Time := 10 ns; + constant SIMULATION_CYCLE_COUNT : integer := 100; signal clk, rst : std_logic; signal cu_to_sb_cmd: command_t; signal cu_to_sb_address: std_logic_vector(31 downto 0); @@ -32,7 +33,7 @@ architecture tb of control_socbridge_tb is driver_id => (others => '0'), address => (others => '0'), seq_mem_access_count => 0, - cmd => x"00" + cmd => "00" ); signal int_control_input: int_control_unit_in_t := (active_driver => (others => '0')); signal ext_control_output: ext_control_unit_out_t; @@ -40,6 +41,43 @@ architecture tb of control_socbridge_tb is signal driver_to_control: driver_to_control_t; signal control_to_driver: control_to_driver_t; + + signal curr_word : std_logic_vector(ext_socbridge_in.payload'length - 1 downto 0); + signal expected_out : std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0); + + procedure fail(error_msg : string) is + begin + wait for CLK_PERIOD; + report "Simulation ending due to: " & error_msg & ". Shutting down..." severity FAILURE; + end procedure; + + procedure check_next_state(correct_state: state_t) is + begin + if(not (correct_state = G_next_state)) then + report "Next State is not what was expected, found " & state_t'image(G_next_state) + & " but expected " & state_t'image(correct_state) severity error; + fail("Next State"); + end if; + end procedure; + + procedure check_data_out(correct_data: std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0)) is + begin + if(not (correct_data = ext_socbridge_out.payload)) then + report "Data out is not what was expected, found " & to_string(ext_socbridge_out.payload) + & " but expected " & to_string(correct_data) severity error; + fail("Data out"); + end if; + end procedure; + + procedure check_parity(correct_data: std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0)) is + begin + if(not (calc_parity(correct_data) = calc_parity(ext_socbridge_out.payload))) then + report "Parity out is not what was expected, found " & std_logic'image(calc_parity(ext_socbridge_out.payload)) + & " but expected " & std_logic'image(calc_parity(correct_data)) severity error; + fail("Parity out"); + end if; + end procedure; + begin socbridge_inst: entity socbridge.socbridge_driver @@ -71,26 +109,383 @@ begin int_control_input.active_driver(0) <= driver_to_control.is_active; - clock_proc: process + control_clock_proc: process begin for i in 0 to 50 loop - wait for cycle / 2; + wait for CLK_PERIOD / 2; clk <= not clk; end loop; wait; - end process clock_proc; + end process control_clock_proc; stimulus_proc: process begin - ext_control_input.address <= x"FB0FB0FB"; - ext_control_input.cmd <= "01"; + ext_control_input.address <= (others => '0'); + ext_control_input.cmd <= "00"; ext_control_input.driver_id <= "1"; - ext_control_input.seq_mem_access_count <= 5; + ext_control_input.seq_mem_access_count <= 2; + wait for 3 * CLK_PERIOD; + ext_control_input.address <= x"FA0FA0FA"; + ext_control_input.cmd <= "01"; + wait until int_control_input.active_driver(0) = '1'; + ext_control_input.address <= (others => '0'); + ext_control_input.cmd <= "00"; + wait until int_control_input.active_driver(0) = '0'; + wait for CLK_PERIOD; + ext_control_input.address <= x"FA0FA0FA"; + ext_control_input.cmd <= "10"; + wait until int_control_input.active_driver(0) = '1'; + ext_control_input.address <= (others => '0'); + ext_control_input.cmd <= "00"; + wait until int_control_input.active_driver(0) = '0'; + wait for CLK_PERIOD; + + + wait; end process stimulus_proc; monitor_proc: process begin - + wait; end process monitor_proc; + ext_socbridge_in.control(1) <= clk; + real_clk_proc: process + begin + for x in 0 to SIMULATION_CYCLE_COUNT*2 loop + clk <= not clk; + wait for CLK_PERIOD / 2; + end loop; + wait; + end process real_clk_proc; + + external_stimulus_signal: process(curr_word) + begin + ext_socbridge_in.payload <= curr_word; + ext_socbridge_in.control(0) <= calc_parity(curr_word); + end process external_stimulus_signal; + + external_stimulus: process + begin + wait for CLK_PERIOD / 1000; + curr_word <= "00000000"; + wait for 999 * CLK_PERIOD / 1000; + wait for 2 * CLK_PERIOD; + wait for CLK_PERIOD / 2; + wait for 4* CLK_PERIOD; + curr_word <= "00001001"; + wait for CLK_PERIOD; + curr_word <= "00000000"; + wait for CLK_PERIOD * 14; + curr_word <= "00101001"; + wait for CLK_PERIOD; + curr_word <= "00000000"; + wait for CLK_PERIOD*5; + curr_word <= "01100001"; + wait for CLK_PERIOD; + curr_word <= "00100000"; + wait for CLK_PERIOD; + curr_word <= "00010000"; + wait for CLK_PERIOD; + curr_word <= "00000000"; + + + wait; + end process external_stimulus; + + internal_stimulus: process + variable input : integer := 0; + begin + int_socbridge_in.is_full_in <= '0'; + int_socbridge_in.write_enable_out <= '0'; + wait for 3 * CLK_PERIOD; + -- stimulus goes here + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + wait until falling_edge(clk); + wait; + end process internal_stimulus; + end architecture tb; diff --git a/src/ganimede/io_type_pkg.vhd b/src/ganimede/io_type_pkg.vhd index a20221b..5d42577 100644 --- a/src/ganimede/io_type_pkg.vhd +++ b/src/ganimede/io_type_pkg.vhd @@ -28,7 +28,7 @@ package io_types is driver_id: std_logic_vector(number_of_drivers - 1 downto 0); address: std_logic_vector(address_width - 1 downto 0); seq_mem_access_count: integer; - cmd: std_logic_vector(inst_word_width - 1 downto 0); + cmd: std_logic_vector(1 downto 0); end record ext_control_unit_in_t; type ext_control_unit_out_t is record From 4c4a651ee78036111ed6117af702c890281fdc15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Mon, 10 Mar 2025 17:19:02 +0100 Subject: [PATCH 34/40] testbench working, all functionality not working --- .../control_socbridge_tb.vhd | 273 ++++++++++ src/controller/control_unit.vhd | 6 + src/ganimede/control_socbridge_tb.vhd | 491 ------------------ src/socbridge/socbridge_driver.vhd | 39 +- src/socbridge/socbridge_driver_tb.vhd | 39 +- src/socbridge/socbridge_driver_tb_pkg.vhd | 25 +- 6 files changed, 350 insertions(+), 523 deletions(-) create mode 100644 src/control_socbridge_merge/control_socbridge_tb.vhd delete mode 100644 src/ganimede/control_socbridge_tb.vhd diff --git a/src/control_socbridge_merge/control_socbridge_tb.vhd b/src/control_socbridge_merge/control_socbridge_tb.vhd new file mode 100644 index 0000000..53ce62f --- /dev/null +++ b/src/control_socbridge_merge/control_socbridge_tb.vhd @@ -0,0 +1,273 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.NUMERIC_STD.all; +library ganimede; +use ganimede.io_types.all; +library socbridge; +use socbridge.socbridge_driver_tb_pkg.all; +library controller; + +entity control_socbridge_tb is +end entity control_socbridge_tb; + +architecture tb of control_socbridge_tb is + + constant CLK_PERIOD : Time := 10 ns; + constant SIMULATION_CYCLE_COUNT : integer := 200; + signal clk, rst : std_logic := '0'; + signal cu_to_sb_cmd: command_t; + signal cu_to_sb_address: std_logic_vector(31 downto 0); + signal cmd_size : positive; + signal ext_socbridge_in : ext_socbridge_in_t := ( + payload => (others => '0'), + control => (others => '0') + ); + signal ext_socbridge_out : ext_socbridge_out_t; + signal int_socbridge_out : int_socbridge_out_t; + signal int_socbridge_in : int_socbridge_in_t := ( + payload => (others => '0'), + write_enable_out => '0', + is_full_in => '0' + ); + signal ext_control_input: ext_control_unit_in_t := ( + driver_id => (others => '0'), + address => (others => '0'), + seq_mem_access_count => 0, + cmd => "00" + ); + signal int_control_input: int_control_unit_in_t := (active_driver => (others => '0')); + signal ext_control_output: ext_control_unit_out_t; + signal int_control_output: int_control_unit_out_t; + + signal driver_to_control: driver_to_control_t; + signal control_to_driver: control_to_driver_t; + + signal curr_word : std_logic_vector(ext_socbridge_in.payload'length - 1 downto 0); + signal expected_out : std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0); + + procedure fail(error_msg : string) is + begin + wait for CLK_PERIOD; + report "Simulation ending due to: " & error_msg & ". Shutting down..." severity FAILURE; + end procedure; + + procedure check_next_state(correct_state: state_t) is + begin + if(not (correct_state = G_next_state)) then + report "Next State is not what was expected, found " & state_t'image(G_next_state) + & " but expected " & state_t'image(correct_state) severity error; + fail("Next State"); + end if; + end procedure; + + procedure check_data_out(correct_data: std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0)) is + begin + if(not (correct_data = ext_socbridge_out.payload)) then + report "Data out is not what was expected, found " & to_string(ext_socbridge_out.payload) + & " but expected " & to_string(correct_data) severity error; + fail("Data out"); + end if; + end procedure; + + procedure check_parity(correct_data: std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0)) is + begin + if(not (calc_parity(correct_data) = calc_parity(ext_socbridge_out.payload))) then + report "Parity out is not what was expected, found " & std_logic'image(calc_parity(ext_socbridge_out.payload)) + & " but expected " & std_logic'image(calc_parity(correct_data)) severity error; + fail("Parity out"); + end if; + end procedure; + +begin + socbridge_inst: entity socbridge.socbridge_driver + port map( + clk => clk, + rst => rst, + ctrl_in => control_to_driver, + ctrl_out => driver_to_control, + ext_in => ext_socbridge_in, + ext_out => ext_socbridge_out, + int_in => int_socbridge_in, + int_out => int_socbridge_out + ); + + control_unit_inst: entity controller.control_unit + port map( + clk => clk, + rst => rst, + ext_control_in => ext_control_input, + ext_control_out => ext_control_output, + int_control_in => int_control_input, + int_control_out => int_control_output + ); + + control_to_driver.address <= int_control_output.address; + control_to_driver.request <= int_control_output.driver_id(0); + control_to_driver.instruction <= int_control_output.instruction; + control_to_driver.seq_mem_access_count <= int_control_output.seq_mem_access_count; + + int_control_input.active_driver(0) <= driver_to_control.is_active; + + ext_socbridge_in.control(1) <= clk; + control_clock_proc: process + begin + for i in 0 to SIMULATION_CYCLE_COUNT - 1 loop + wait for CLK_PERIOD / 2; + clk <= not clk; + end loop; + wait; + end process control_clock_proc; + + stimulus_proc: process + begin + report "Starting Simulation Stimulus!"; + rst <= '1'; + ext_control_input.address <= (others => '0'); + ext_control_input.cmd <= "00"; + ext_control_input.driver_id <= "1"; + ext_control_input.seq_mem_access_count <= 2; + wait for 3 * CLK_PERIOD; + report "Reset grace period ended, starting stimulus..."; + rst <= '0'; + ext_control_input.address <= x"FA0FA0FA"; + ext_control_input.cmd <= "01"; + wait until int_control_input.active_driver(0) = '1'; + report "Task received in driver, awaiting completion..."; + ext_control_input.address <= (others => '0'); + ext_control_input.cmd <= "00"; + wait until int_control_input.active_driver(0) = '0'; + wait for CLK_PERIOD; + report "Task completed in driver, sending next task..."; + ext_control_input.address <= x"FA0FA0FA"; + ext_control_input.cmd <= "10"; + wait for CLK_PERIOD; + wait until int_control_input.active_driver(0) = '1'; + report "Task received in driver, awaiting completion..."; + ext_control_input.address <= (others => '0'); + ext_control_input.cmd <= "00"; + wait until int_control_input.active_driver(0) = '0'; + wait for CLK_PERIOD; + report "Task completed in driver, ending simulation stimulus"; + + wait; + end process stimulus_proc; + + external_stimulus_signal: process(curr_word) + begin + ext_socbridge_in.payload <= curr_word; + ext_socbridge_in.control(0) <= calc_parity(curr_word); + end process external_stimulus_signal; + + external_stimulus: process + begin + wait for CLK_PERIOD / 1000; + curr_word <= "00000000"; + wait for 999 * CLK_PERIOD / 1000; + wait for 2 * CLK_PERIOD; + wait for CLK_PERIOD / 2; + wait for 10* CLK_PERIOD; + curr_word <= "00001001"; + wait for CLK_PERIOD; + curr_word <= "00000000"; + wait for CLK_PERIOD * 20; + curr_word <= "00101001"; + wait for CLK_PERIOD; + curr_word <= "00000000"; + wait for CLK_PERIOD*10; + curr_word <= "01100001"; + wait for CLK_PERIOD; + curr_word <= "00100000"; + wait for CLK_PERIOD; + curr_word <= "00010000"; + wait for CLK_PERIOD; + curr_word <= "00000000"; + + + wait; + end process external_stimulus; + + internal_stimulus: process + variable input : positive := 1; + begin + int_socbridge_in.is_full_in <= '0'; + int_socbridge_in.write_enable_out <= '0'; + wait for 3 * CLK_PERIOD; + -- stimulus goes here + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + int_socbridge_in.write_enable_out <= '1'; + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + wait; + end process internal_stimulus; + +end architecture tb; diff --git a/src/controller/control_unit.vhd b/src/controller/control_unit.vhd index 00a4f5d..0371216 100644 --- a/src/controller/control_unit.vhd +++ b/src/controller/control_unit.vhd @@ -63,6 +63,12 @@ begin state.instruction <= WRITE when "01", READ when "10", NO_OP when others; + else + state <= ((others => '0'), + 0, + (others => '0'), + '1', + NO_OP); end if; end if; end if; diff --git a/src/ganimede/control_socbridge_tb.vhd b/src/ganimede/control_socbridge_tb.vhd deleted file mode 100644 index 0c46ec0..0000000 --- a/src/ganimede/control_socbridge_tb.vhd +++ /dev/null @@ -1,491 +0,0 @@ -library IEEE; -use IEEE.std_logic_1164.all; -use IEEE.NUMERIC_STD.all; -library ganimede; -use ganimede.io_types.all; -library socbridge; -use socbridge.socbridge_driver_tb_pkg.all; -library controller; - -entity control_socbridge_tb is -end entity control_socbridge_tb; - -architecture tb of control_socbridge_tb is - - constant CLK_PERIOD : Time := 10 ns; - constant SIMULATION_CYCLE_COUNT : integer := 100; - signal clk, rst : std_logic; - signal cu_to_sb_cmd: command_t; - signal cu_to_sb_address: std_logic_vector(31 downto 0); - signal cmd_size : positive; - signal ext_socbridge_in : ext_socbridge_in_t := ( - payload => (others => '0'), - control => (others => '0') - ); - signal ext_socbridge_out : ext_socbridge_out_t; - signal int_socbridge_out : int_socbridge_out_t; - signal int_socbridge_in : int_socbridge_in_t := ( - payload => (others => '0'), - write_enable_out => '0', - is_full_in => '0' - ); - signal ext_control_input: ext_control_unit_in_t := ( - driver_id => (others => '0'), - address => (others => '0'), - seq_mem_access_count => 0, - cmd => "00" - ); - signal int_control_input: int_control_unit_in_t := (active_driver => (others => '0')); - signal ext_control_output: ext_control_unit_out_t; - signal int_control_output: int_control_unit_out_t; - - signal driver_to_control: driver_to_control_t; - signal control_to_driver: control_to_driver_t; - - signal curr_word : std_logic_vector(ext_socbridge_in.payload'length - 1 downto 0); - signal expected_out : std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0); - - procedure fail(error_msg : string) is - begin - wait for CLK_PERIOD; - report "Simulation ending due to: " & error_msg & ". Shutting down..." severity FAILURE; - end procedure; - - procedure check_next_state(correct_state: state_t) is - begin - if(not (correct_state = G_next_state)) then - report "Next State is not what was expected, found " & state_t'image(G_next_state) - & " but expected " & state_t'image(correct_state) severity error; - fail("Next State"); - end if; - end procedure; - - procedure check_data_out(correct_data: std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0)) is - begin - if(not (correct_data = ext_socbridge_out.payload)) then - report "Data out is not what was expected, found " & to_string(ext_socbridge_out.payload) - & " but expected " & to_string(correct_data) severity error; - fail("Data out"); - end if; - end procedure; - - procedure check_parity(correct_data: std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0)) is - begin - if(not (calc_parity(correct_data) = calc_parity(ext_socbridge_out.payload))) then - report "Parity out is not what was expected, found " & std_logic'image(calc_parity(ext_socbridge_out.payload)) - & " but expected " & std_logic'image(calc_parity(correct_data)) severity error; - fail("Parity out"); - end if; - end procedure; - -begin - - socbridge_inst: entity socbridge.socbridge_driver - port map( - clk => clk, - rst => rst, - ctrl_in => control_to_driver, - ctrl_out => driver_to_control, - ext_in => ext_socbridge_in, - ext_out => ext_socbridge_out, - int_in => int_socbridge_in, - int_out => int_socbridge_out - ); - - control_unit_inst: entity controller.control_unit - port map( - clk => clk, - rst => rst, - ext_control_in => ext_control_input, - ext_control_out => ext_control_output, - int_control_in => int_control_input, - int_control_out => int_control_output - ); - - control_to_driver.address <= int_control_output.address; - control_to_driver.request <= int_control_output.driver_id(0); - control_to_driver.instruction <= int_control_output.instruction; - control_to_driver.seq_mem_access_count <= int_control_output.seq_mem_access_count; - - int_control_input.active_driver(0) <= driver_to_control.is_active; - - control_clock_proc: process - begin - for i in 0 to 50 loop - wait for CLK_PERIOD / 2; - clk <= not clk; - end loop; - wait; - end process control_clock_proc; - - stimulus_proc: process - begin - ext_control_input.address <= (others => '0'); - ext_control_input.cmd <= "00"; - ext_control_input.driver_id <= "1"; - ext_control_input.seq_mem_access_count <= 2; - wait for 3 * CLK_PERIOD; - ext_control_input.address <= x"FA0FA0FA"; - ext_control_input.cmd <= "01"; - wait until int_control_input.active_driver(0) = '1'; - ext_control_input.address <= (others => '0'); - ext_control_input.cmd <= "00"; - wait until int_control_input.active_driver(0) = '0'; - wait for CLK_PERIOD; - ext_control_input.address <= x"FA0FA0FA"; - ext_control_input.cmd <= "10"; - wait until int_control_input.active_driver(0) = '1'; - ext_control_input.address <= (others => '0'); - ext_control_input.cmd <= "00"; - wait until int_control_input.active_driver(0) = '0'; - wait for CLK_PERIOD; - - - wait; - end process stimulus_proc; - - monitor_proc: process - begin - wait; - end process monitor_proc; - - ext_socbridge_in.control(1) <= clk; - real_clk_proc: process - begin - for x in 0 to SIMULATION_CYCLE_COUNT*2 loop - clk <= not clk; - wait for CLK_PERIOD / 2; - end loop; - wait; - end process real_clk_proc; - - external_stimulus_signal: process(curr_word) - begin - ext_socbridge_in.payload <= curr_word; - ext_socbridge_in.control(0) <= calc_parity(curr_word); - end process external_stimulus_signal; - - external_stimulus: process - begin - wait for CLK_PERIOD / 1000; - curr_word <= "00000000"; - wait for 999 * CLK_PERIOD / 1000; - wait for 2 * CLK_PERIOD; - wait for CLK_PERIOD / 2; - wait for 4* CLK_PERIOD; - curr_word <= "00001001"; - wait for CLK_PERIOD; - curr_word <= "00000000"; - wait for CLK_PERIOD * 14; - curr_word <= "00101001"; - wait for CLK_PERIOD; - curr_word <= "00000000"; - wait for CLK_PERIOD*5; - curr_word <= "01100001"; - wait for CLK_PERIOD; - curr_word <= "00100000"; - wait for CLK_PERIOD; - curr_word <= "00010000"; - wait for CLK_PERIOD; - curr_word <= "00000000"; - - - wait; - end process external_stimulus; - - internal_stimulus: process - variable input : integer := 0; - begin - int_socbridge_in.is_full_in <= '0'; - int_socbridge_in.write_enable_out <= '0'; - wait for 3 * CLK_PERIOD; - -- stimulus goes here - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - wait until falling_edge(clk); - wait; - end process internal_stimulus; - -end architecture tb; diff --git a/src/socbridge/socbridge_driver.vhd b/src/socbridge/socbridge_driver.vhd index fb5bf3c..7b51634 100644 --- a/src/socbridge/socbridge_driver.vhd +++ b/src/socbridge/socbridge_driver.vhd @@ -13,9 +13,6 @@ entity socbridge_driver is rst : in std_logic; ctrl_in : in control_to_driver_t; ctrl_out: out driver_to_control_t; - -- cmd : in command_t; - -- address : in std_logic_vector(31 downto 0); - -- cmd_size: in positive; ext_in : in ext_socbridge_in_t; ext_out : out ext_socbridge_out_t; int_out : out int_socbridge_out_t; @@ -50,6 +47,7 @@ begin G_curr_response <= curr_response; G_curr_response_bits <= curr_response_bits; G_st <= st; + G_trans_st <= trans_st; -- synthesis translate_on ext_in_rec.data <= ext_in.payload; ext_in_rec.clk <= ext_in.control(1); @@ -263,13 +261,16 @@ begin -- Wait for driver to go idle and send next instruction. Then enter AWAIT when SEND => if st.curr_state /= IDLE then - trans_next_state <= AWAIT; + trans_next_state <= SEND_ACCEPTED; else trans_next_state <= SEND; end if; + -- Transisitonal state to decrement counter in transition between SEND and AWAIT. + when SEND_ACCEPTED => + trans_next_state <= AWAIT; -- Wait for driver to finish current instruction, then reenter SEND when AWAIT => - if trans_st.curr_inst.seq_mem_access_count <= 0 then + if trans_st.curr_inst.seq_mem_access_count <= 0 and st.curr_state = IDLE then trans_next_state <= IDLE; elsif st.curr_state = IDLE then trans_next_state <= SEND; @@ -300,10 +301,12 @@ begin if trans_st.curr_inst.seq_mem_access_count > 256 then next_cmd_size <= 256; - else + elsif trans_st.curr_inst.seq_mem_access_count > 0 then next_cmd_size <= trans_st.curr_inst.seq_mem_access_count; + else + next_cmd_size <= 0; end if; - when AWAIT => + when others => end case; end process comb_proc; @@ -335,18 +338,27 @@ begin st.curr_cmd <= next_cmd; st.curr_cmd_size <= next_cmd_size; st.curr_addr <= trans_st.curr_inst.address; + if next_cmd_size > 0 then + st.write_stage <= next_cmd_size - 1; + st.read_stage <= next_cmd_size - 1; + end if; when TX_HEADER => - st.write_stage <= 2**(st.curr_cmd_size - 1) - 1; when TX_BODY => if st.write_stage > 0 then st.write_stage <= st.write_stage - 1; end if; + when TX_ACK => + st.curr_cmd <= NO_OP; + st.curr_cmd_size <= 0; when RX_HEADER => - st.read_stage <= 2**(st.curr_cmd_size - 1) - 1; when RX_BODY => if st.read_stage > 0 then st.read_stage <= st.read_stage - 1; + else + st.curr_cmd <= NO_OP; + st.curr_cmd_size <= 0; end if; + when others => end case; end if; @@ -366,10 +378,19 @@ begin when IDLE => if ctrl_in.request = '1' then trans_st.curr_inst <= ctrl_in; + else end if; + trans_st.is_first_word <= '1'; when SEND => + when SEND_ACCEPTED => trans_st.curr_inst.seq_mem_access_count <= trans_st.curr_inst.seq_mem_access_count - 256; when AWAIT => + if trans_st.curr_inst.seq_mem_access_count <= 0 and st.curr_state = IDLE then + trans_st.curr_inst.request <= '0'; + trans_st.curr_inst.address <= (others => '0'); + trans_st.curr_inst.seq_mem_access_count <= 0; + trans_st.curr_inst.instruction <= NO_OP; + end if; trans_st.is_first_word <= '0'; when others => end case; diff --git a/src/socbridge/socbridge_driver_tb.vhd b/src/socbridge/socbridge_driver_tb.vhd index 25a67fc..75bd29c 100644 --- a/src/socbridge/socbridge_driver_tb.vhd +++ b/src/socbridge/socbridge_driver_tb.vhd @@ -21,6 +21,8 @@ architecture tb of socbridge_driver_tb is signal ext_out : ext_socbridge_out_t; signal int_in : int_socbridge_in_t; signal int_out : int_socbridge_out_t; + signal ctrl_in : control_to_driver_t; + signal ctrl_out : driver_to_control_t; signal curr_word : std_logic_vector(ext_in.payload'length - 1 downto 0); signal expected_out : std_logic_vector(ext_out.payload'length - 1 downto 0); @@ -79,9 +81,8 @@ begin port map( clk => clk, rst => rst, - cmd => cmd, - address => address, - cmd_size => cmd_size, + ctrl_in => ctrl_in, + ctrl_out => ctrl_out, ext_in => ext_in, ext_out => ext_out, int_in => int_in, @@ -113,7 +114,6 @@ begin end process verify_clk; verify_out_signals: process - variable curr_parity : std_logic; begin wait for CLK_PERIOD / 2; for x in 0 to SIMULATION_CYCLE_COUNT loop @@ -125,7 +125,6 @@ begin end process verify_out_signals; verify_signals : process - variable nsv: boolean; begin expected_out <= "00000000"; wait for 3 * CLK_PERIOD; @@ -306,30 +305,30 @@ begin internal_stimulus: process begin - int_out.is_full_in <= '0'; - int_out.write_enable_out <= '0'; + int_in.is_full_in <= '0'; + int_in.write_enable_out <= '0'; wait for 3 * CLK_PERIOD; -- stimulus goes here - int_out.write_enable_out <= '1'; - int_out.payload <= "00000001"; - wait until rising_edge(clk) and int_in.is_full_out = '0'; + int_in.write_enable_out <= '1'; + int_in.payload <= "00000001"; + wait until rising_edge(clk) and int_out.is_full_out = '0'; wait until falling_edge(clk); - int_out.payload <= "00000010"; - wait until rising_edge(clk) and int_in.is_full_out = '0'; + int_in.payload <= "00000010"; + wait until rising_edge(clk) and int_out.is_full_out = '0'; wait until falling_edge(clk); - int_out.payload <= "00000100"; - wait until rising_edge(clk) and int_in.is_full_out = '0'; + int_in.payload <= "00000100"; + wait until rising_edge(clk) and int_out.is_full_out = '0'; wait until falling_edge(clk); - int_out.payload <= "00001000"; - wait until rising_edge(clk) and int_in.is_full_out = '0'; + int_in.payload <= "00001000"; + wait until rising_edge(clk) and int_out.is_full_out = '0'; wait until falling_edge(clk); - int_out.payload <= "00010000"; - wait until int_in.is_full_out = '0'; + int_in.payload <= "00010000"; + wait until int_out.is_full_out = '0'; wait for CLK_PERIOD/2; wait until rising_edge(clk); wait until rising_edge(clk); - int_out.payload <= "00100000"; - wait until int_in.is_full_out = '0'; + int_in.payload <= "00100000"; + wait until int_out.is_full_out = '0'; wait for CLK_PERIOD/2; wait until rising_edge(clk); wait until rising_edge(clk); --- ??? Why all these rising_edge checks? diff --git a/src/socbridge/socbridge_driver_tb_pkg.vhd b/src/socbridge/socbridge_driver_tb_pkg.vhd index 060d8e8..f5febce 100644 --- a/src/socbridge/socbridge_driver_tb_pkg.vhd +++ b/src/socbridge/socbridge_driver_tb_pkg.vhd @@ -7,7 +7,7 @@ use ganimede.io_types.all; package socbridge_driver_tb_pkg is - subtype command_size_t is integer range 1 to 128; + subtype command_size_t is integer range 0 to 128; type command_t is (NO_OP, WRITE_ADD, WRITE, READ_ADD, READ, P_ERR); @@ -21,7 +21,7 @@ package socbridge_driver_tb_pkg is RX_HEADER, RX_RESPONSE, RX_BODY_NO_OUT, RX_BODY); --- TRANSLATOR --- - type translator_state_t is (IDLE, SEND, AWAIT); + type translator_state_t is (IDLE, SEND, SEND_ACCEPTED, AWAIT); type translator_state_rec_t is record curr_inst : control_to_driver_t; @@ -64,6 +64,7 @@ package socbridge_driver_tb_pkg is signal G_curr_response : response_t; signal G_curr_response_bits : std_logic_vector(4 downto 0); signal G_st : state_rec_t; + signal G_trans_st : translator_state_rec_t; -- synthesis translate_on end package socbridge_driver_tb_pkg; @@ -91,6 +92,8 @@ package body socbridge_driver_tb_pkg is end loop; return not parity; end function; + + pure function create_io_type_out_from_ext_protocol( input : ext_protocol_t @@ -122,7 +125,23 @@ package body socbridge_driver_tb_pkg is return std_logic_vector is variable val : std_logic_vector(2 downto 0); begin - val := std_logic_vector(TO_UNSIGNED(size - 1, 3)); + if size > 2**6 then + val := "111"; + elsif size > 2**5 then + val := "110"; + elsif size > 2**4 then + val := "101"; + elsif size > 2**3 then + val := "100"; + elsif size > 2**2 then + val := "011"; + elsif size > 2**1 then + val := "010"; + elsif size > 2**0 then + val := "001"; + elsif size >= 0 then + val := "000"; + end if; return val; end function; pure function get_size_bits_sim(size: command_size_t) From 82278e77cf49cbb144a07ff8c837557f724f79d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Tue, 11 Mar 2025 14:55:25 +0100 Subject: [PATCH 35/40] fixed data not coming through. writes were problematic in tb, reads in socbridge --- src/control_socbridge_merge/control_socbridge_tb.vhd | 3 ++- src/socbridge/socbridge_driver.vhd | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/control_socbridge_merge/control_socbridge_tb.vhd b/src/control_socbridge_merge/control_socbridge_tb.vhd index 53ce62f..af9aa82 100644 --- a/src/control_socbridge_merge/control_socbridge_tb.vhd +++ b/src/control_socbridge_merge/control_socbridge_tb.vhd @@ -173,7 +173,7 @@ begin curr_word <= "00101001"; wait for CLK_PERIOD; curr_word <= "00000000"; - wait for CLK_PERIOD*10; + wait for CLK_PERIOD*20; curr_word <= "01100001"; wait for CLK_PERIOD; curr_word <= "00100000"; @@ -197,6 +197,7 @@ begin int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); input := input + 1 mod 256; wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); int_socbridge_in.write_enable_out <= '1'; int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); input := input + 1 mod 256; diff --git a/src/socbridge/socbridge_driver.vhd b/src/socbridge/socbridge_driver.vhd index 7b51634..3177494 100644 --- a/src/socbridge/socbridge_driver.vhd +++ b/src/socbridge/socbridge_driver.vhd @@ -166,7 +166,7 @@ begin when RX_RESPONSE => -- Wait for read response. if curr_response = READ_RESPONSE then - next_state <= RX_BODY_NO_OUT; + next_state <= RX_BODY; else next_state <= RX_RESPONSE; end if; @@ -241,6 +241,7 @@ begin if st.curr_cmd = WRITE_ADD then int_out.is_full_out <= '0'; ext_out_data_cmd := int_in.payload; + report integer'image(to_integer(signed(ext_out_data_cmd))) & " "& integer'image(to_integer(signed(int_in.payload))); end if; end case; next_parity_out <= calc_parity(ext_out_data_cmd); From c96300f6fcdae34e13805e39bd4ebc9f09c46ba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Tue, 11 Mar 2025 15:10:21 +0100 Subject: [PATCH 36/40] tested and fixed socbridge for multimessage packets --- .../control_socbridge_tb.vhd | 85 +++---------------- src/socbridge/socbridge_driver.vhd | 6 +- 2 files changed, 15 insertions(+), 76 deletions(-) diff --git a/src/control_socbridge_merge/control_socbridge_tb.vhd b/src/control_socbridge_merge/control_socbridge_tb.vhd index af9aa82..e8ad87d 100644 --- a/src/control_socbridge_merge/control_socbridge_tb.vhd +++ b/src/control_socbridge_merge/control_socbridge_tb.vhd @@ -13,7 +13,7 @@ end entity control_socbridge_tb; architecture tb of control_socbridge_tb is constant CLK_PERIOD : Time := 10 ns; - constant SIMULATION_CYCLE_COUNT : integer := 200; + constant SIMULATION_CYCLE_COUNT : integer := 2000; signal clk, rst : std_logic := '0'; signal cu_to_sb_cmd: command_t; signal cu_to_sb_address: std_logic_vector(31 downto 0); @@ -125,7 +125,7 @@ begin ext_control_input.address <= (others => '0'); ext_control_input.cmd <= "00"; ext_control_input.driver_id <= "1"; - ext_control_input.seq_mem_access_count <= 2; + ext_control_input.seq_mem_access_count <= 256; wait for 3 * CLK_PERIOD; report "Reset grace period ended, starting stimulus..."; rst <= '0'; @@ -137,6 +137,7 @@ begin ext_control_input.cmd <= "00"; wait until int_control_input.active_driver(0) = '0'; wait for CLK_PERIOD; + ext_control_input.seq_mem_access_count <= 2; report "Task completed in driver, sending next task..."; ext_control_input.address <= x"FA0FA0FA"; ext_control_input.cmd <= "10"; @@ -169,10 +170,12 @@ begin curr_word <= "00001001"; wait for CLK_PERIOD; curr_word <= "00000000"; - wait for CLK_PERIOD * 20; + wait for CLK_PERIOD * 140; curr_word <= "00101001"; wait for CLK_PERIOD; curr_word <= "00000000"; + wait for CLK_PERIOD * 140; + curr_word <= "00101001"; wait for CLK_PERIOD*20; curr_word <= "01100001"; wait for CLK_PERIOD; @@ -198,76 +201,12 @@ begin input := input + 1 mod 256; wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); - input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; - wait until falling_edge(clk); + for x in 0 to 1000 loop + int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + input := input + 1 mod 256; + wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until falling_edge(clk); + end loop; wait; end process internal_stimulus; diff --git a/src/socbridge/socbridge_driver.vhd b/src/socbridge/socbridge_driver.vhd index 3177494..86b4f9d 100644 --- a/src/socbridge/socbridge_driver.vhd +++ b/src/socbridge/socbridge_driver.vhd @@ -300,8 +300,8 @@ begin end if; end if; - if trans_st.curr_inst.seq_mem_access_count > 256 then - next_cmd_size <= 256; + if trans_st.curr_inst.seq_mem_access_count > 128 then + next_cmd_size <= 128; elsif trans_st.curr_inst.seq_mem_access_count > 0 then next_cmd_size <= trans_st.curr_inst.seq_mem_access_count; else @@ -384,7 +384,7 @@ begin trans_st.is_first_word <= '1'; when SEND => when SEND_ACCEPTED => - trans_st.curr_inst.seq_mem_access_count <= trans_st.curr_inst.seq_mem_access_count - 256; + trans_st.curr_inst.seq_mem_access_count <= trans_st.curr_inst.seq_mem_access_count - 128; when AWAIT => if trans_st.curr_inst.seq_mem_access_count <= 0 and st.curr_state = IDLE then trans_st.curr_inst.request <= '0'; From 9979b7b6dd182baa99039f9978ef1f8c10076c4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Tue, 11 Mar 2025 15:34:39 +0100 Subject: [PATCH 37/40] tested, fixed and verified multimessage packet reads --- .../control_socbridge_tb.vhd | 31 ++++++++++++++----- src/socbridge/socbridge_driver.vhd | 3 -- src/socbridge/socbridge_driver_tb.vhd | 6 ---- src/socbridge/socbridge_driver_tb_pkg.vhd | 2 +- 4 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/control_socbridge_merge/control_socbridge_tb.vhd b/src/control_socbridge_merge/control_socbridge_tb.vhd index e8ad87d..d3dc4e2 100644 --- a/src/control_socbridge_merge/control_socbridge_tb.vhd +++ b/src/control_socbridge_merge/control_socbridge_tb.vhd @@ -137,7 +137,6 @@ begin ext_control_input.cmd <= "00"; wait until int_control_input.active_driver(0) = '0'; wait for CLK_PERIOD; - ext_control_input.seq_mem_access_count <= 2; report "Task completed in driver, sending next task..."; ext_control_input.address <= x"FA0FA0FA"; ext_control_input.cmd <= "10"; @@ -149,6 +148,10 @@ begin wait until int_control_input.active_driver(0) = '0'; wait for CLK_PERIOD; report "Task completed in driver, ending simulation stimulus"; + ext_control_input.address <= (others => '0'); + ext_control_input.cmd <= "00"; + ext_control_input.driver_id <= "0"; + ext_control_input.seq_mem_access_count <= 0; wait; end process stimulus_proc; @@ -160,6 +163,7 @@ begin end process external_stimulus_signal; external_stimulus: process + variable input : positive := 1; begin wait for CLK_PERIOD / 1000; curr_word <= "00000000"; @@ -176,15 +180,26 @@ begin curr_word <= "00000000"; wait for CLK_PERIOD * 140; curr_word <= "00101001"; - wait for CLK_PERIOD*20; - curr_word <= "01100001"; - wait for CLK_PERIOD; - curr_word <= "00100000"; - wait for CLK_PERIOD; - curr_word <= "00010000"; wait for CLK_PERIOD; curr_word <= "00000000"; - + wait for CLK_PERIOD * 20; + curr_word <= "01100111"; + wait for CLK_PERIOD; + for x in 0 to 127 loop + curr_word <= std_logic_vector(to_unsigned(input, 8)); + input := input + 1 mod 256; + wait for CLK_PERIOD; + end loop; + curr_word <= "00000000"; + wait for CLK_PERIOD * 140; + wait for CLK_PERIOD * 20; + curr_word <= "01100111"; + wait for CLK_PERIOD; + for x in 0 to 127 loop + curr_word <= std_logic_vector(to_unsigned(input, 8)); + input := input + 1 mod 256; + wait for CLK_PERIOD; + end loop; wait; end process external_stimulus; diff --git a/src/socbridge/socbridge_driver.vhd b/src/socbridge/socbridge_driver.vhd index 86b4f9d..0d8fb57 100644 --- a/src/socbridge/socbridge_driver.vhd +++ b/src/socbridge/socbridge_driver.vhd @@ -170,8 +170,6 @@ begin else next_state <= RX_RESPONSE; end if; - when RX_BODY_NO_OUT => - next_state <= RX_BODY; when RX_BODY => -- Here we want to stay in RX_BODY for the duration of a packet. if st.read_stage = 0 then @@ -227,7 +225,6 @@ begin ext_out_data_cmd := st.curr_addr(7 downto 0); end if; when RX_RESPONSE => - when RX_BODY_NO_OUT => when RX_BODY => int_out.payload <= st.ext_in_reg.data; int_out.write_enable_in <= '1'; diff --git a/src/socbridge/socbridge_driver_tb.vhd b/src/socbridge/socbridge_driver_tb.vhd index 75bd29c..8ac24a5 100644 --- a/src/socbridge/socbridge_driver_tb.vhd +++ b/src/socbridge/socbridge_driver_tb.vhd @@ -189,9 +189,6 @@ begin expected_out <= "00000000"; check_next_state(RX_RESPONSE); wait for CLK_PERIOD; - wait for CLK_PERIOD / 4; - check_next_state(RX_BODY_NO_OUT); - wait for CLK_PERIOD * 3 /4; check_next_state(RX_BODY); wait for CLK_PERIOD; check_next_state(RX_BODY); @@ -219,9 +216,6 @@ begin expected_out <= "00000000"; check_next_state(RX_RESPONSE); wait for CLK_PERIOD; - wait for CLK_PERIOD / 4; - check_next_state(RX_BODY_NO_OUT); - wait for CLK_PERIOD * 3 /4; check_next_state(RX_BODY); wait for CLK_PERIOD; check_next_state(RX_BODY); diff --git a/src/socbridge/socbridge_driver_tb_pkg.vhd b/src/socbridge/socbridge_driver_tb_pkg.vhd index f5febce..1c4bc46 100644 --- a/src/socbridge/socbridge_driver_tb_pkg.vhd +++ b/src/socbridge/socbridge_driver_tb_pkg.vhd @@ -18,7 +18,7 @@ package socbridge_driver_tb_pkg is type state_t is (IDLE, ADDR1, ADDR2, ADDR3, ADDR4, TX_HEADER, TX_BODY, TX_ACK, - RX_HEADER, RX_RESPONSE, RX_BODY_NO_OUT, RX_BODY); + RX_HEADER, RX_RESPONSE, RX_BODY); --- TRANSLATOR --- type translator_state_t is (IDLE, SEND, SEND_ACCEPTED, AWAIT); From dba8b1a86d4252a270a3ca3cc9b81eebcccf37d1 Mon Sep 17 00:00:00 2001 From: Adam Magnusson Date: Wed, 12 Mar 2025 16:05:50 +0100 Subject: [PATCH 38/40] started refactoring signal names --- .../control_socbridge_tb.vhd | 66 +++++++++---------- src/controller/control_unit.vhd | 30 ++++----- src/ganimede/io_type_pkg.vhd | 34 +++++----- 3 files changed, 65 insertions(+), 65 deletions(-) diff --git a/src/control_socbridge_merge/control_socbridge_tb.vhd b/src/control_socbridge_merge/control_socbridge_tb.vhd index d3dc4e2..89be5fb 100644 --- a/src/control_socbridge_merge/control_socbridge_tb.vhd +++ b/src/control_socbridge_merge/control_socbridge_tb.vhd @@ -29,15 +29,15 @@ architecture tb of control_socbridge_tb is write_enable_out => '0', is_full_in => '0' ); - signal ext_control_input: ext_control_unit_in_t := ( + signal cpu_to_controller: cpu_to_controller_t := ( driver_id => (others => '0'), address => (others => '0'), seq_mem_access_count => 0, cmd => "00" ); - signal int_control_input: int_control_unit_in_t := (active_driver => (others => '0')); - signal ext_control_output: ext_control_unit_out_t; - signal int_control_output: int_control_unit_out_t; + signal driver_to_controller: driver_to_control_t := (is_active => '0'); + signal controller_to_cpu: controller_to_cpu_t; + signal controller_to_driver: controller_to_driver_t; signal driver_to_control: driver_to_control_t; signal control_to_driver: control_to_driver_t; @@ -95,18 +95,18 @@ begin port map( clk => clk, rst => rst, - ext_control_in => ext_control_input, - ext_control_out => ext_control_output, - int_control_in => int_control_input, - int_control_out => int_control_output + cpu_to_controller => cpu_to_controller, + controller_to_cpu => controller_to_cpu, + driver_to_controller => driver_to_controller, + controller_to_driver => controller_to_driver ); - control_to_driver.address <= int_control_output.address; - control_to_driver.request <= int_control_output.driver_id(0); - control_to_driver.instruction <= int_control_output.instruction; - control_to_driver.seq_mem_access_count <= int_control_output.seq_mem_access_count; + control_to_driver.address <= controller_to_driver.address; + control_to_driver.request <= controller_to_driver.driver_id(0); + control_to_driver.instruction <= controller_to_driver.instruction; + control_to_driver.seq_mem_access_count <= controller_to_driver.seq_mem_access_count; - int_control_input.active_driver(0) <= driver_to_control.is_active; + driver_to_controller.active_driver(0) <= driver_to_control.is_active; ext_socbridge_in.control(1) <= clk; control_clock_proc: process @@ -122,36 +122,36 @@ begin begin report "Starting Simulation Stimulus!"; rst <= '1'; - ext_control_input.address <= (others => '0'); - ext_control_input.cmd <= "00"; - ext_control_input.driver_id <= "1"; - ext_control_input.seq_mem_access_count <= 256; + cpu_to_controller.address <= (others => '0'); + cpu_to_controller.cmd <= "00"; + cpu_to_controller.driver_id <= "1"; + cpu_to_controller.seq_mem_access_count <= 256; wait for 3 * CLK_PERIOD; report "Reset grace period ended, starting stimulus..."; rst <= '0'; - ext_control_input.address <= x"FA0FA0FA"; - ext_control_input.cmd <= "01"; - wait until int_control_input.active_driver(0) = '1'; + cpu_to_controller.address <= x"FA0FA0FA"; + cpu_to_controller.cmd <= "01"; + wait until driver_to_controller.active_driver(0) = '1'; report "Task received in driver, awaiting completion..."; - ext_control_input.address <= (others => '0'); - ext_control_input.cmd <= "00"; - wait until int_control_input.active_driver(0) = '0'; + cpu_to_controller.address <= (others => '0'); + cpu_to_controller.cmd <= "00"; + wait until driver_to_controller.active_driver(0) = '0'; wait for CLK_PERIOD; report "Task completed in driver, sending next task..."; - ext_control_input.address <= x"FA0FA0FA"; - ext_control_input.cmd <= "10"; + cpu_to_controller.address <= x"FA0FA0FA"; + cpu_to_controller.cmd <= "10"; wait for CLK_PERIOD; - wait until int_control_input.active_driver(0) = '1'; + wait until driver_to_controller.active_driver(0) = '1'; report "Task received in driver, awaiting completion..."; - ext_control_input.address <= (others => '0'); - ext_control_input.cmd <= "00"; - wait until int_control_input.active_driver(0) = '0'; + cpu_to_controller.address <= (others => '0'); + cpu_to_controller.cmd <= "00"; + wait until driver_to_controller.active_driver(0) = '0'; wait for CLK_PERIOD; report "Task completed in driver, ending simulation stimulus"; - ext_control_input.address <= (others => '0'); - ext_control_input.cmd <= "00"; - ext_control_input.driver_id <= "0"; - ext_control_input.seq_mem_access_count <= 0; + cpu_to_controller.address <= (others => '0'); + cpu_to_controller.cmd <= "00"; + cpu_to_controller.driver_id <= "0"; + cpu_to_controller.seq_mem_access_count <= 0; wait; end process stimulus_proc; diff --git a/src/controller/control_unit.vhd b/src/controller/control_unit.vhd index 0371216..060ee27 100644 --- a/src/controller/control_unit.vhd +++ b/src/controller/control_unit.vhd @@ -8,10 +8,10 @@ entity control_unit is port ( clk, rst : in std_logic; - ext_control_in : in ext_control_unit_in_t; - ext_control_out : out ext_control_unit_out_t; - int_control_in : in int_control_unit_in_t; - int_control_out : out int_control_unit_out_t + cpu_to_controller : in cpu_to_controller_t; + controller_to_cpu : out controller_to_cpu_t; + driver_to_controller : in driver_to_controller_t; + controller_to_driver : out controller_to_driver_t ); end entity control_unit; @@ -31,17 +31,17 @@ architecture behave of control_unit is begin - comb_proc: process(ext_control_in, int_control_in, state) + comb_proc: process(cpu_to_controller, driver_to_controller, state) begin ored := '0'; ready_reduction: for i in 0 to number_of_drivers - 1 loop - ored := ored or int_control_in.active_driver(i); + ored := ored or driver_to_controller.active_driver(i); end loop ready_reduction; - int_control_out.driver_id <= state.curr_driver; - int_control_out.address <= state.address; - int_control_out.seq_mem_access_count <= state.seq_mem_access_count; - ext_control_out.ready <= state.ready; - int_control_out.instruction <= state.instruction; + controller_to_driver.driver_id <= state.curr_driver; + controller_to_driver.address <= state.address; + controller_to_driver.seq_mem_access_count <= state.seq_mem_access_count; + controller_to_cpu.ready <= state.ready; + controller_to_driver.instruction <= state.instruction; end process comb_proc; sync_proc: process(clk, state) @@ -56,10 +56,10 @@ begin else state.ready <= not ored; if ored = '0' then - state.address <= ext_control_in.address; - state.seq_mem_access_count <= ext_control_in.seq_mem_access_count; - state.curr_driver <= ext_control_in.driver_id; - with ext_control_in.cmd select + state.address <= cpu_to_controller.address; + state.seq_mem_access_count <= cpu_to_controller.seq_mem_access_count; + state.curr_driver <= cpu_to_controller.driver_id; + with cpu_to_controller.cmd select state.instruction <= WRITE when "01", READ when "10", NO_OP when others; diff --git a/src/ganimede/io_type_pkg.vhd b/src/ganimede/io_type_pkg.vhd index 5d42577..07b4118 100644 --- a/src/ganimede/io_type_pkg.vhd +++ b/src/ganimede/io_type_pkg.vhd @@ -24,38 +24,38 @@ package io_types is end record interface_inst_t; --- CONTROL UNIT --- - type ext_control_unit_in_t is record + type cpu_to_controller_t is record driver_id: std_logic_vector(number_of_drivers - 1 downto 0); address: std_logic_vector(address_width - 1 downto 0); seq_mem_access_count: integer; cmd: std_logic_vector(1 downto 0); - end record ext_control_unit_in_t; + end record cpu_to_controller_t; - type ext_control_unit_out_t is record + type controller_to_cpu_t is record ready: std_logic; - end record ext_control_unit_out_t; + end record controller_to_cpu_t; - type int_control_unit_out_t is record - driver_id: std_logic_vector(number_of_drivers - 1 downto 0); - address: std_logic_vector(address_width - 1 downto 0); - seq_mem_access_count: integer; - instruction: instruction_command_t; - end record int_control_unit_out_t; + --type controller_to_driver_t is record + -- driver_id: std_logic_vector(number_of_drivers - 1 downto 0); + -- address: std_logic_vector(address_width - 1 downto 0); + -- seq_mem_access_count: integer; + -- instruction: instruction_command_t; + --end record controller_to_driver_t; - type int_control_unit_in_t is record - active_driver: std_logic_vector(number_of_drivers - 1 downto 0); - end record int_control_unit_in_t; + --type driver_to_controller_t is record + -- active_driver: std_logic_vector(number_of_drivers - 1 downto 0); + --end record driver_to_controller_t; - type driver_to_control_t is record + type driver_to_controller_t is record is_active : std_logic; - end record driver_to_control_t; + end record driver_to_controller_t; - type control_to_driver_t is record + type controller_to_driver_t is record request: std_logic; address: std_logic_vector(address_width - 1 downto 0); seq_mem_access_count: integer; instruction: instruction_command_t; - end record control_to_driver_t; + end record controller_to_driver_t; --- PROTOCOL INFORMATION --- constant interface_inst : interface_inst_t := ( From 695745c198c0a76d94ed614020d7e026d994bde0 Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 12 Mar 2025 16:45:44 +0100 Subject: [PATCH 39/40] continued refatctoring. Still not done --- .../control_socbridge_tb.vhd | 36 +++++++------------ src/socbridge/socbridge_driver.vhd | 8 ++--- src/socbridge/socbridge_driver_tb.vhd | 4 +-- src/socbridge/socbridge_driver_tb_pkg.vhd | 8 ++--- 4 files changed, 23 insertions(+), 33 deletions(-) diff --git a/src/control_socbridge_merge/control_socbridge_tb.vhd b/src/control_socbridge_merge/control_socbridge_tb.vhd index 89be5fb..b32bfe8 100644 --- a/src/control_socbridge_merge/control_socbridge_tb.vhd +++ b/src/control_socbridge_merge/control_socbridge_tb.vhd @@ -7,10 +7,10 @@ library socbridge; use socbridge.socbridge_driver_tb_pkg.all; library controller; -entity control_socbridge_tb is -end entity control_socbridge_tb; +entity controller_socbridge_tb is +end entity controller_socbridge_tb; -architecture tb of control_socbridge_tb is +architecture tb of controller_socbridge_tb is constant CLK_PERIOD : Time := 10 ns; constant SIMULATION_CYCLE_COUNT : integer := 2000; @@ -35,13 +35,10 @@ architecture tb of control_socbridge_tb is seq_mem_access_count => 0, cmd => "00" ); - signal driver_to_controller: driver_to_control_t := (is_active => '0'); + signal driver_to_controller: driver_to_controller_t := (is_active => '0'); signal controller_to_cpu: controller_to_cpu_t; signal controller_to_driver: controller_to_driver_t; - signal driver_to_control: driver_to_control_t; - signal control_to_driver: control_to_driver_t; - signal curr_word : std_logic_vector(ext_socbridge_in.payload'length - 1 downto 0); signal expected_out : std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0); @@ -83,15 +80,15 @@ begin port map( clk => clk, rst => rst, - ctrl_in => control_to_driver, - ctrl_out => driver_to_control, + ctrl_in => controller_to_driver, + ctrl_out => driver_to_controller, ext_in => ext_socbridge_in, ext_out => ext_socbridge_out, int_in => int_socbridge_in, int_out => int_socbridge_out ); - control_unit_inst: entity controller.control_unit + controller_unit_inst: entity controller.control_unit port map( clk => clk, rst => rst, @@ -101,22 +98,15 @@ begin controller_to_driver => controller_to_driver ); - control_to_driver.address <= controller_to_driver.address; - control_to_driver.request <= controller_to_driver.driver_id(0); - control_to_driver.instruction <= controller_to_driver.instruction; - control_to_driver.seq_mem_access_count <= controller_to_driver.seq_mem_access_count; - - driver_to_controller.active_driver(0) <= driver_to_control.is_active; - ext_socbridge_in.control(1) <= clk; - control_clock_proc: process + controller_clock_proc: process begin for i in 0 to SIMULATION_CYCLE_COUNT - 1 loop wait for CLK_PERIOD / 2; clk <= not clk; end loop; wait; - end process control_clock_proc; + end process controller_clock_proc; stimulus_proc: process begin @@ -131,21 +121,21 @@ begin rst <= '0'; cpu_to_controller.address <= x"FA0FA0FA"; cpu_to_controller.cmd <= "01"; - wait until driver_to_controller.active_driver(0) = '1'; + wait until driver_to_controller.is_active = '1'; report "Task received in driver, awaiting completion..."; cpu_to_controller.address <= (others => '0'); cpu_to_controller.cmd <= "00"; - wait until driver_to_controller.active_driver(0) = '0'; + wait until driver_to_controller.is_active = '0'; wait for CLK_PERIOD; report "Task completed in driver, sending next task..."; cpu_to_controller.address <= x"FA0FA0FA"; cpu_to_controller.cmd <= "10"; wait for CLK_PERIOD; - wait until driver_to_controller.active_driver(0) = '1'; + wait until driver_to_controller.is_active = '1'; report "Task received in driver, awaiting completion..."; cpu_to_controller.address <= (others => '0'); cpu_to_controller.cmd <= "00"; - wait until driver_to_controller.active_driver(0) = '0'; + wait until driver_to_controller.is_active = '0'; wait for CLK_PERIOD; report "Task completed in driver, ending simulation stimulus"; cpu_to_controller.address <= (others => '0'); diff --git a/src/socbridge/socbridge_driver.vhd b/src/socbridge/socbridge_driver.vhd index 0d8fb57..b85fdaa 100644 --- a/src/socbridge/socbridge_driver.vhd +++ b/src/socbridge/socbridge_driver.vhd @@ -11,10 +11,10 @@ entity socbridge_driver is port( clk : in std_logic; rst : in std_logic; - ctrl_in : in control_to_driver_t; - ctrl_out: out driver_to_control_t; - ext_in : in ext_socbridge_in_t; - ext_out : out ext_socbridge_out_t; + ctrl_in : in controller_to_driver_t; + ctrl_out: out driver_to_controller_t; + ext_in : in ext_to_socbridge_driver_t; + ext_out : out socbridge_driver_to_ext_t; int_out : out int_socbridge_out_t; int_in : in int_socbridge_in_t ); diff --git a/src/socbridge/socbridge_driver_tb.vhd b/src/socbridge/socbridge_driver_tb.vhd index 8ac24a5..671c5e9 100644 --- a/src/socbridge/socbridge_driver_tb.vhd +++ b/src/socbridge/socbridge_driver_tb.vhd @@ -21,8 +21,8 @@ architecture tb of socbridge_driver_tb is signal ext_out : ext_socbridge_out_t; signal int_in : int_socbridge_in_t; signal int_out : int_socbridge_out_t; - signal ctrl_in : control_to_driver_t; - signal ctrl_out : driver_to_control_t; + signal ctrl_in : controller_to_driver_t; + signal ctrl_out : driver_to_controller_t; signal curr_word : std_logic_vector(ext_in.payload'length - 1 downto 0); signal expected_out : std_logic_vector(ext_out.payload'length - 1 downto 0); diff --git a/src/socbridge/socbridge_driver_tb_pkg.vhd b/src/socbridge/socbridge_driver_tb_pkg.vhd index 1c4bc46..b8dee28 100644 --- a/src/socbridge/socbridge_driver_tb_pkg.vhd +++ b/src/socbridge/socbridge_driver_tb_pkg.vhd @@ -24,7 +24,7 @@ package socbridge_driver_tb_pkg is type translator_state_t is (IDLE, SEND, SEND_ACCEPTED, AWAIT); type translator_state_rec_t is record - curr_inst : control_to_driver_t; + curr_inst : controller_to_driver_t; curr_state : translator_state_t; is_first_word : std_logic; end record translator_state_rec_t; @@ -48,7 +48,7 @@ package socbridge_driver_tb_pkg is ) return std_logic; pure function create_io_type_out_from_ext_protocol( input: ext_protocol_t - ) return ext_socbridge_out_t; + ) return socbridge_driver_to_ext_t; function to_string ( a: std_logic_vector) return string; pure function get_cmd_bits(command : command_t) return std_logic_vector; pure function get_size_bits(size : command_size_t) return std_logic_vector; @@ -97,8 +97,8 @@ package body socbridge_driver_tb_pkg is pure function create_io_type_out_from_ext_protocol( input : ext_protocol_t - ) return ext_socbridge_out_t is - variable val : ext_socbridge_out_t; + ) return socbridge_driver_to_ext_t is + variable val : socbridge_driver_to_ext_t; begin val.payload:= input.data; val.control(1) := input.clk; From c3d3cef7c9d3c9c5d1aa16060f910e328048df89 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 13 Mar 2025 16:28:39 +0100 Subject: [PATCH 40/40] Refactoring done --- .../control_socbridge_tb.vhd | 102 ++++++------- src/controller/control_unit.vhd | 24 +-- src/controller/control_unit_tb.vhd | 34 ++--- src/ganimede/ganimede.vhd | 8 +- src/ganimede/io_type_pkg.vhd | 40 ++--- src/socbridge/socbridge_driver.vhd | 140 +++++++++--------- src/socbridge/socbridge_driver_tb.vhd | 88 +++++------ src/socbridge/socbridge_driver_tb_pkg.vhd | 8 +- 8 files changed, 221 insertions(+), 223 deletions(-) diff --git a/src/control_socbridge_merge/control_socbridge_tb.vhd b/src/control_socbridge_merge/control_socbridge_tb.vhd index b32bfe8..dc15769 100644 --- a/src/control_socbridge_merge/control_socbridge_tb.vhd +++ b/src/control_socbridge_merge/control_socbridge_tb.vhd @@ -7,24 +7,24 @@ library socbridge; use socbridge.socbridge_driver_tb_pkg.all; library controller; -entity controller_socbridge_tb is -end entity controller_socbridge_tb; +entity control_socbridge_tb is +end entity control_socbridge_tb; -architecture tb of controller_socbridge_tb is +architecture tb of control_socbridge_tb is - constant CLK_PERIOD : Time := 10 ns; - constant SIMULATION_CYCLE_COUNT : integer := 2000; - signal clk, rst : std_logic := '0'; - signal cu_to_sb_cmd: command_t; - signal cu_to_sb_address: std_logic_vector(31 downto 0); - signal cmd_size : positive; - signal ext_socbridge_in : ext_socbridge_in_t := ( + constant CLK_PERIOD : Time := 10 ns; + constant SIMULATION_CYCLE_COUNT : integer := 2000; + signal clk, rst : std_logic := '0'; + signal controller_to_socbridge_driver_cmd : command_t; + signal controller_to_socbridge_driver_address : std_logic_vector(31 downto 0); + signal cmd_size : positive; + signal ext_to_socbridge_driver : ext_to_socbridge_driver_t := ( payload => (others => '0'), control => (others => '0') ); - signal ext_socbridge_out : ext_socbridge_out_t; - signal int_socbridge_out : int_socbridge_out_t; - signal int_socbridge_in : int_socbridge_in_t := ( + signal socbridge_driver_to_ext : socbridge_driver_to_ext_t; + signal socbridge_driver_to_buffer : socbridge_driver_to_buffer_t; + signal buffer_to_socbridge_driver : buffer_to_socbridge_driver_t := ( payload => (others => '0'), write_enable_out => '0', is_full_in => '0' @@ -35,12 +35,12 @@ architecture tb of controller_socbridge_tb is seq_mem_access_count => 0, cmd => "00" ); - signal driver_to_controller: driver_to_controller_t := (is_active => '0'); + signal socbridge_driver_to_controller: socbridge_driver_to_controller_t := (is_active => '0'); signal controller_to_cpu: controller_to_cpu_t; - signal controller_to_driver: controller_to_driver_t; + signal controller_to_socbridge_driver: controller_to_socbridge_driver_t; - signal curr_word : std_logic_vector(ext_socbridge_in.payload'length - 1 downto 0); - signal expected_out : std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0); + signal curr_word : std_logic_vector(ext_to_socbridge_driver.payload'length - 1 downto 0); + signal expected_out : std_logic_vector(socbridge_driver_to_ext.payload'length - 1 downto 0); procedure fail(error_msg : string) is begin @@ -57,19 +57,19 @@ architecture tb of controller_socbridge_tb is end if; end procedure; - procedure check_data_out(correct_data: std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0)) is + procedure check_data_out(correct_data: std_logic_vector(socbridge_driver_to_ext.payload'length - 1 downto 0)) is begin - if(not (correct_data = ext_socbridge_out.payload)) then - report "Data out is not what was expected, found " & to_string(ext_socbridge_out.payload) + if(not (correct_data = socbridge_driver_to_ext.payload)) then + report "Data out is not what was expected, found " & to_string(socbridge_driver_to_ext.payload) & " but expected " & to_string(correct_data) severity error; fail("Data out"); end if; end procedure; - procedure check_parity(correct_data: std_logic_vector(ext_socbridge_out.payload'length - 1 downto 0)) is + procedure check_parity(correct_data: std_logic_vector(socbridge_driver_to_ext.payload'length - 1 downto 0)) is begin - if(not (calc_parity(correct_data) = calc_parity(ext_socbridge_out.payload))) then - report "Parity out is not what was expected, found " & std_logic'image(calc_parity(ext_socbridge_out.payload)) + if(not (calc_parity(correct_data) = calc_parity(socbridge_driver_to_ext.payload))) then + report "Parity out is not what was expected, found " & std_logic'image(calc_parity(socbridge_driver_to_ext.payload)) & " but expected " & std_logic'image(calc_parity(correct_data)) severity error; fail("Parity out"); end if; @@ -78,27 +78,27 @@ architecture tb of controller_socbridge_tb is begin socbridge_inst: entity socbridge.socbridge_driver port map( - clk => clk, - rst => rst, - ctrl_in => controller_to_driver, - ctrl_out => driver_to_controller, - ext_in => ext_socbridge_in, - ext_out => ext_socbridge_out, - int_in => int_socbridge_in, - int_out => int_socbridge_out + clk => clk, + rst => rst, + controller_to_socbridge_driver => controller_to_socbridge_driver, + socbridge_driver_to_controller => socbridge_driver_to_controller, + ext_to_socbridge_driver => ext_to_socbridge_driver, + socbridge_driver_to_ext => socbridge_driver_to_ext, + buffer_to_socbridge_driver => buffer_to_socbridge_driver, + socbridge_driver_to_buffer => socbridge_driver_to_buffer ); controller_unit_inst: entity controller.control_unit port map( - clk => clk, - rst => rst, - cpu_to_controller => cpu_to_controller, - controller_to_cpu => controller_to_cpu, - driver_to_controller => driver_to_controller, - controller_to_driver => controller_to_driver + clk => clk, + rst => rst, + cpu_to_controller => cpu_to_controller, + controller_to_cpu => controller_to_cpu, + socbridge_driver_to_controller => socbridge_driver_to_controller, + controller_to_socbridge_driver => controller_to_socbridge_driver ); - ext_socbridge_in.control(1) <= clk; + ext_to_socbridge_driver.control(1) <= clk; controller_clock_proc: process begin for i in 0 to SIMULATION_CYCLE_COUNT - 1 loop @@ -121,21 +121,21 @@ begin rst <= '0'; cpu_to_controller.address <= x"FA0FA0FA"; cpu_to_controller.cmd <= "01"; - wait until driver_to_controller.is_active = '1'; + wait until socbridge_driver_to_controller.is_active = '1'; report "Task received in driver, awaiting completion..."; cpu_to_controller.address <= (others => '0'); cpu_to_controller.cmd <= "00"; - wait until driver_to_controller.is_active = '0'; + wait until socbridge_driver_to_controller.is_active = '0'; wait for CLK_PERIOD; report "Task completed in driver, sending next task..."; cpu_to_controller.address <= x"FA0FA0FA"; cpu_to_controller.cmd <= "10"; wait for CLK_PERIOD; - wait until driver_to_controller.is_active = '1'; + wait until socbridge_driver_to_controller.is_active = '1'; report "Task received in driver, awaiting completion..."; cpu_to_controller.address <= (others => '0'); cpu_to_controller.cmd <= "00"; - wait until driver_to_controller.is_active = '0'; + wait until socbridge_driver_to_controller.is_active = '0'; wait for CLK_PERIOD; report "Task completed in driver, ending simulation stimulus"; cpu_to_controller.address <= (others => '0'); @@ -148,8 +148,8 @@ begin external_stimulus_signal: process(curr_word) begin - ext_socbridge_in.payload <= curr_word; - ext_socbridge_in.control(0) <= calc_parity(curr_word); + ext_to_socbridge_driver.payload <= curr_word; + ext_to_socbridge_driver.control(0) <= calc_parity(curr_word); end process external_stimulus_signal; external_stimulus: process @@ -197,19 +197,19 @@ begin internal_stimulus: process variable input : positive := 1; begin - int_socbridge_in.is_full_in <= '0'; - int_socbridge_in.write_enable_out <= '0'; + buffer_to_socbridge_driver.is_full_in <= '0'; + buffer_to_socbridge_driver.write_enable_out <= '0'; wait for 3 * CLK_PERIOD; -- stimulus goes here - int_socbridge_in.write_enable_out <= '1'; - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + buffer_to_socbridge_driver.write_enable_out <= '1'; + buffer_to_socbridge_driver.payload <= std_logic_vector(to_unsigned(input, buffer_to_socbridge_driver.payload'length)); input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until rising_edge(clk) and socbridge_driver_to_buffer.is_full_out = '0'; wait until falling_edge(clk); for x in 0 to 1000 loop - int_socbridge_in.payload <= std_logic_vector(to_unsigned(input, int_socbridge_in.payload'length)); + buffer_to_socbridge_driver.payload <= std_logic_vector(to_unsigned(input, buffer_to_socbridge_driver.payload'length)); input := input + 1 mod 256; - wait until rising_edge(clk) and int_socbridge_out.is_full_out = '0'; + wait until rising_edge(clk) and socbridge_driver_to_buffer.is_full_out = '0'; wait until falling_edge(clk); end loop; wait; diff --git a/src/controller/control_unit.vhd b/src/controller/control_unit.vhd index 060ee27..66f4870 100644 --- a/src/controller/control_unit.vhd +++ b/src/controller/control_unit.vhd @@ -10,8 +10,8 @@ entity control_unit is clk, rst : in std_logic; cpu_to_controller : in cpu_to_controller_t; controller_to_cpu : out controller_to_cpu_t; - driver_to_controller : in driver_to_controller_t; - controller_to_driver : out controller_to_driver_t + socbridge_driver_to_controller : in socbridge_driver_to_controller_t; + controller_to_socbridge_driver : out controller_to_socbridge_driver_t ); end entity control_unit; @@ -20,7 +20,7 @@ architecture behave of control_unit is type state_t is record address: std_logic_vector(address_width - 1 downto 0); seq_mem_access_count: integer; - curr_driver: std_logic_vector(number_of_drivers - 1 downto 0); --one-hot encoded, 0 means disabled + curr_driver: std_logic; ready: std_logic; instruction: instruction_command_t; end record state_t; @@ -31,17 +31,17 @@ architecture behave of control_unit is begin - comb_proc: process(cpu_to_controller, driver_to_controller, state) + comb_proc: process(cpu_to_controller, socbridge_driver_to_controller, state) begin ored := '0'; ready_reduction: for i in 0 to number_of_drivers - 1 loop - ored := ored or driver_to_controller.active_driver(i); + ored := ored or socbridge_driver_to_controller.is_active; end loop ready_reduction; - controller_to_driver.driver_id <= state.curr_driver; - controller_to_driver.address <= state.address; - controller_to_driver.seq_mem_access_count <= state.seq_mem_access_count; + controller_to_socbridge_driver.request <= state.curr_driver; + controller_to_socbridge_driver.address <= state.address; + controller_to_socbridge_driver.seq_mem_access_count <= state.seq_mem_access_count; controller_to_cpu.ready <= state.ready; - controller_to_driver.instruction <= state.instruction; + controller_to_socbridge_driver.instruction <= state.instruction; end process comb_proc; sync_proc: process(clk, state) @@ -50,7 +50,7 @@ begin if rst = '1' then state <= ((others => '0'), 0, - (others => '0'), + '0', '1', NO_OP); else @@ -58,7 +58,7 @@ begin if ored = '0' then state.address <= cpu_to_controller.address; state.seq_mem_access_count <= cpu_to_controller.seq_mem_access_count; - state.curr_driver <= cpu_to_controller.driver_id; + state.curr_driver <= cpu_to_controller.driver_id(0); with cpu_to_controller.cmd select state.instruction <= WRITE when "01", READ when "10", @@ -66,7 +66,7 @@ begin else state <= ((others => '0'), 0, - (others => '0'), + '0', '1', NO_OP); end if; diff --git a/src/controller/control_unit_tb.vhd b/src/controller/control_unit_tb.vhd index bad377e..905166d 100644 --- a/src/controller/control_unit_tb.vhd +++ b/src/controller/control_unit_tb.vhd @@ -14,14 +14,14 @@ architecture tb of control_unit_tb is constant cycle: Time := 10 ns; signal clock: std_logic := '0'; signal reset: std_logic := '0'; - signal ext_control_input: ext_control_unit_in_t := ( + signal cpu_to_controller: cpu_to_controller_t := ( (others => '0'), (others => '0'), 0, "00"); - signal int_control_input: int_control_unit_in_t := (active_driver => (others => '0')); - signal ext_control_output: ext_control_unit_out_t; - signal int_control_output: int_control_unit_out_t; + signal socbridge_driver_to_controller: socbridge_driver_to_controller_t := (is_active => '0'); + signal controller_to_cpu: controller_to_cpu_t; + signal controller_to_socbridge_driver: controller_to_socbridge_driver_t; signal current_driver : std_logic_vector(0 downto 0) := "0"; shared variable word_counter: natural := 0; @@ -40,21 +40,21 @@ begin port map( clk => clock, rst => reset, - ext_control_in => ext_control_input, - ext_control_out => ext_control_output, - int_control_in => int_control_input, - int_control_out => int_control_output + cpu_to_controller => cpu_to_controller, + controller_to_cpu => controller_to_cpu, + socbridge_driver_to_controller => socbridge_driver_to_controller, + controller_to_socbridge_driver => controller_to_socbridge_driver ); stimulus_proc: process begin wait for cycle; - ext_control_input.driver_id <= "1"; - int_control_input.active_driver <= "0"; - ext_control_input.address <= x"F0F0F0F0"; - ext_control_input.seq_mem_access_count <= 3; - ext_control_input.cmd <= "01"; + cpu_to_controller.driver_id <= "1"; + socbridge_driver_to_controller.is_active <= '0'; + cpu_to_controller.address <= x"F0F0F0F0"; + cpu_to_controller.seq_mem_access_count <= 3; + cpu_to_controller.cmd <= "01"; word_counter := 3; wait for cycle; current_driver <= "1"; @@ -65,7 +65,7 @@ begin report "words remaining are " & integer'image(i); end loop for_loop; - int_control_input.active_driver <= "0"; + socbridge_driver_to_controller.is_active <= '0'; report "Stim process done"; wait; end process stimulus_proc; @@ -76,9 +76,9 @@ begin wait for cycle; wait for cycle; - assert int_control_output.driver_id = "1" report "Incorrect driver_id from control_unit" severity error; - assert int_control_output.address = x"F0F0F0F0" report "Incorrect address from control_unit" severity error; - assert int_control_output.instruction = WRITE report "Incorrect memory op from control_unit" severity error; + assert controller_to_socbridge_driver.request = '1' report "Incorrect driver_id from control_unit" severity error; + assert controller_to_socbridge_driver.address = x"F0F0F0F0" report "Incorrect address from control_unit" severity error; + assert controller_to_socbridge_driver.instruction = WRITE report "Incorrect memory op from control_unit" severity error; wait for 5 * cycle; reset <= '1'; diff --git a/src/ganimede/ganimede.vhd b/src/ganimede/ganimede.vhd index e95d003..7bcb720 100644 --- a/src/ganimede/ganimede.vhd +++ b/src/ganimede/ganimede.vhd @@ -43,10 +43,10 @@ architecture rtl of ganimede is port( clk : in std_logic; reset : in std_logic; - ext_in : in ext_socbridge_in_t; - ext_out : out ext_socbridge_out_t; - int_in : out int_socbridge_in_t; - int_out : in int_socbridge_out_t + ext_in : in ext_to_socbridge_driver_t; + ext_out : out socbridge_driver_to_ext_t; + int_in : out buffer_to_socbridge_driver_t; + int_out : in socbridge_driver_to_buffer_t ); end component; diff --git a/src/ganimede/io_type_pkg.vhd b/src/ganimede/io_type_pkg.vhd index 07b4118..ed67ad3 100644 --- a/src/ganimede/io_type_pkg.vhd +++ b/src/ganimede/io_type_pkg.vhd @@ -35,27 +35,27 @@ package io_types is ready: std_logic; end record controller_to_cpu_t; - --type controller_to_driver_t is record + --type controller_to_socbridge_driver_t is record -- driver_id: std_logic_vector(number_of_drivers - 1 downto 0); -- address: std_logic_vector(address_width - 1 downto 0); -- seq_mem_access_count: integer; -- instruction: instruction_command_t; - --end record controller_to_driver_t; + --end record controller_to_socbridge_driver_t; - --type driver_to_controller_t is record + --type socbridge_driver_to_controller_t is record -- active_driver: std_logic_vector(number_of_drivers - 1 downto 0); - --end record driver_to_controller_t; + --end record socbridge_driver_to_controller_t; - type driver_to_controller_t is record + type socbridge_driver_to_controller_t is record is_active : std_logic; - end record driver_to_controller_t; + end record socbridge_driver_to_controller_t; - type controller_to_driver_t is record + type controller_to_socbridge_driver_t is record request: std_logic; address: std_logic_vector(address_width - 1 downto 0); seq_mem_access_count: integer; instruction: instruction_command_t; - end record controller_to_driver_t; + end record controller_to_socbridge_driver_t; --- PROTOCOL INFORMATION --- constant interface_inst : interface_inst_t := ( @@ -63,40 +63,40 @@ package io_types is ); --- AUTOGENERATED TYPES --- - type ext_socbridge_in_t is record + type ext_to_socbridge_driver_t is record payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); control : STD_LOGIC_VECTOR(interface_inst.socbridge.control_width_in - 1 downto 0); - end record ext_socbridge_in_t; + end record ext_to_socbridge_driver_t; - type ext_socbridge_out_t is record + type socbridge_driver_to_ext_t is record payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); control : STD_LOGIC_VECTOR(interface_inst.socbridge.control_width_in - 1 downto 0); - end record ext_socbridge_out_t; + end record socbridge_driver_to_ext_t; - type int_socbridge_out_t is record + type socbridge_driver_to_buffer_t is record payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); write_enable_in, is_full_out : std_logic; - end record int_socbridge_out_t; + end record socbridge_driver_to_buffer_t; - type int_socbridge_in_t is record + type buffer_to_socbridge_driver_t is record payload : STD_LOGIC_VECTOR(interface_inst.socbridge.payload_width - 1 downto 0); write_enable_out, is_full_in : std_logic; - end record int_socbridge_in_t; + end record buffer_to_socbridge_driver_t; type ext_interface_in_t is record - socbridge : ext_socbridge_in_t; + socbridge : ext_to_socbridge_driver_t; end record ext_interface_in_t; type ext_interface_out_t is record - socbridge : ext_socbridge_out_t; + socbridge : socbridge_driver_to_ext_t; end record ext_interface_out_t; type int_interface_out_t is record - socbridge : int_socbridge_out_t; + socbridge : socbridge_driver_to_buffer_t; end record int_interface_out_t; type int_interface_in_t is record - socbridge : int_socbridge_in_t; + socbridge : buffer_to_socbridge_driver_t; end record int_interface_in_t; end package io_types; diff --git a/src/socbridge/socbridge_driver.vhd b/src/socbridge/socbridge_driver.vhd index b85fdaa..449a32e 100644 --- a/src/socbridge/socbridge_driver.vhd +++ b/src/socbridge/socbridge_driver.vhd @@ -9,30 +9,30 @@ use socbridge.socbridge_driver_tb_pkg.all; entity socbridge_driver is port( - clk : in std_logic; - rst : in std_logic; - ctrl_in : in controller_to_driver_t; - ctrl_out: out driver_to_controller_t; - ext_in : in ext_to_socbridge_driver_t; - ext_out : out socbridge_driver_to_ext_t; - int_out : out int_socbridge_out_t; - int_in : in int_socbridge_in_t + clk : in std_logic; + rst : in std_logic; + controller_to_socbridge_driver : in controller_to_socbridge_driver_t; + socbridge_driver_to_controller : out socbridge_driver_to_controller_t; + ext_to_socbridge_driver : in ext_to_socbridge_driver_t; + socbridge_driver_to_ext : out socbridge_driver_to_ext_t; + socbridge_driver_to_buffer : out socbridge_driver_to_buffer_t; + buffer_to_socbridge_driver : in buffer_to_socbridge_driver_t ); end entity socbridge_driver; architecture rtl of socbridge_driver is - signal next_parity_out : std_logic; - signal ext_in_rec : ext_protocol_t; - shared variable ext_out_data_cmd : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); - signal test : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); - signal next_cmd : command_t; - signal next_cmd_size : integer; - signal next_state : state_t; - signal curr_cmd_bits : std_logic_vector(4 downto 0); - signal curr_response : response_t; - signal curr_response_bits : std_logic_vector(4 downto 0); - signal st : state_rec_t; + signal next_parity_out : std_logic; + signal ext_to_socbridge_driver_rec : ext_protocol_t; + shared variable socbridge_driver_to_ext_data_cmd : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); + signal test : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); + signal next_cmd : command_t; + signal next_cmd_size : integer; + signal next_state : state_t; + signal curr_cmd_bits : std_logic_vector(4 downto 0); + signal curr_response : response_t; + signal curr_response_bits : std_logic_vector(4 downto 0); + signal st : state_rec_t; --- TRANSLATOR --- signal trans_st : translator_state_rec_t; signal trans_next_state : translator_state_t; @@ -40,32 +40,32 @@ begin --- DEBUG GLOBAL BINDINGS --- -- synthesis translate_off G_next_parity_out <= next_parity_out; - G_ext_in_rec <= ext_in_rec; + G_ext_to_socbridge_driver_rec <= ext_to_socbridge_driver_rec; G_next_state <= next_state; - G_ext_out_data_cmd <=test; + G_socbridge_driver_to_ext_data_cmd <=test; G_curr_command_bits <= curr_cmd_bits; G_curr_response <= curr_response; G_curr_response_bits <= curr_response_bits; G_st <= st; G_trans_st <= trans_st; -- synthesis translate_on - ext_in_rec.data <= ext_in.payload; - ext_in_rec.clk <= ext_in.control(1); - ext_in_rec.parity <= ext_in.control(0); + 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); -- Helpful Bindings -- - curr_response_bits <= ext_in.payload(7 downto 3); -- CANT USE EXT_IN_REC here for some reason, the assignment becomes stasteful + curr_response_bits <= ext_to_socbridge_driver.payload(7 downto 3); -- CANT USE ext_to_socbridge_driver_REC here for some reason, the assignment becomes stasteful -- Not sure that the two process method is helping here: if this was a normal -- signal assignment there would be no confusion. - -- in the case ... <= ext_in_rec we get - -- curr_resp | ext_in_rec | ext_in + -- in the case ... <= ext_to_socbridge_driver_rec we get + -- curr_resp | ext_to_socbridge_driver_rec | ext_to_socbridge_driver -- 00000 | 00000000 | 00001001 -- 00000 | 00001001 | 00001001 -- 00001 | 00001001 | 00001001 -- 00001 | 00001001 | 00001001 -- - -- but in the case ... <= ext_in we get - -- curr_resp | ext_in_rec | ext_in + -- but in the case ... <= ext_to_socbridge_driver we get + -- curr_resp | ext_to_socbridge_driver_rec | ext_to_socbridge_driver -- 00000 | 00000000 | 00001001 -- 00001 | 00001001 | 00001001 -- 00001 | 00001001 | 00001001 @@ -77,12 +77,12 @@ begin READ_RESPONSE when "01000", READ_RESPONSE when "01100", NO_OP when others; - comb_proc: process(ext_in, int_in, curr_response, st, ctrl_in, trans_st) + comb_proc: process(ext_to_socbridge_driver, buffer_to_socbridge_driver, curr_response, st, controller_to_socbridge_driver, trans_st) begin -- Outputs - ext_out <= create_io_type_out_from_ext_protocol(st.ext_out_reg); + socbridge_driver_to_ext <= create_io_type_out_from_ext_protocol(st.socbridge_driver_to_ext_reg); with trans_st.curr_state select - ctrl_out.is_active <= '0' when IDLE, + socbridge_driver_to_controller.is_active <= '0' when IDLE, '1' when others; --- State Transition Diagram --- @@ -193,58 +193,58 @@ begin end case; --- Combinatorial output based on current state --- - ext_out_data_cmd := (others => '0'); - int_out.is_full_out <= '1'; - int_out.write_enable_in <= '0'; - int_out.payload <= (others => '0'); + socbridge_driver_to_ext_data_cmd := (others => '0'); + socbridge_driver_to_buffer.is_full_out <= '1'; + socbridge_driver_to_buffer.write_enable_in <= '0'; + socbridge_driver_to_buffer.payload <= (others => '0'); case st.curr_state is when IDLE => if st.curr_cmd = WRITE or st.curr_cmd = WRITE_ADD then - ext_out_data_cmd := get_cmd_bits(st.curr_cmd) & get_size_bits(st.curr_cmd_size); + socbridge_driver_to_ext_data_cmd := get_cmd_bits(st.curr_cmd) & get_size_bits(st.curr_cmd_size); elsif st.curr_cmd = READ or st.curr_cmd = READ_ADD then - ext_out_data_cmd := get_cmd_bits(st.curr_cmd) & get_size_bits(st.curr_cmd_size); + socbridge_driver_to_ext_data_cmd := get_cmd_bits(st.curr_cmd) & get_size_bits(st.curr_cmd_size); else end if; when TX_HEADER => if st.curr_cmd = WRITE_ADD then - ext_out_data_cmd := st.curr_addr(7 downto 0); + socbridge_driver_to_ext_data_cmd := st.curr_addr(7 downto 0); else - ext_out_data_cmd := int_in.payload; - int_out.is_full_out <= '0'; + socbridge_driver_to_ext_data_cmd := buffer_to_socbridge_driver.payload; + socbridge_driver_to_buffer.is_full_out <= '0'; end if; when TX_BODY => if st.write_stage > 0 then - int_out.is_full_out <= '0'; - ext_out_data_cmd := int_in.payload; + socbridge_driver_to_buffer.is_full_out <= '0'; + socbridge_driver_to_ext_data_cmd := buffer_to_socbridge_driver.payload; else - ext_out_data_cmd := (others => '0'); + socbridge_driver_to_ext_data_cmd := (others => '0'); end if; when TX_ACK => when RX_HEADER => if st.curr_cmd = READ_ADD then - ext_out_data_cmd := st.curr_addr(7 downto 0); + socbridge_driver_to_ext_data_cmd := st.curr_addr(7 downto 0); end if; when RX_RESPONSE => when RX_BODY => - int_out.payload <= st.ext_in_reg.data; - int_out.write_enable_in <= '1'; + socbridge_driver_to_buffer.payload <= st.ext_to_socbridge_driver_reg.data; + socbridge_driver_to_buffer.write_enable_in <= '1'; when ADDR1 => - ext_out_data_cmd := st.curr_addr(15 downto 8); + socbridge_driver_to_ext_data_cmd := st.curr_addr(15 downto 8); when ADDR2 => - ext_out_data_cmd := st.curr_addr(23 downto 16); + socbridge_driver_to_ext_data_cmd := st.curr_addr(23 downto 16); when ADDR3 => - ext_out_data_cmd := st.curr_addr(31 downto 24); + socbridge_driver_to_ext_data_cmd := st.curr_addr(31 downto 24); when ADDR4 => if st.curr_cmd = WRITE_ADD then - int_out.is_full_out <= '0'; - ext_out_data_cmd := int_in.payload; - report integer'image(to_integer(signed(ext_out_data_cmd))) & " "& integer'image(to_integer(signed(int_in.payload))); + socbridge_driver_to_buffer.is_full_out <= '0'; + socbridge_driver_to_ext_data_cmd := buffer_to_socbridge_driver.payload; + report integer'image(to_integer(signed(socbridge_driver_to_ext_data_cmd))) & " "& integer'image(to_integer(signed(buffer_to_socbridge_driver.payload))); end if; end case; - next_parity_out <= calc_parity(ext_out_data_cmd); + next_parity_out <= calc_parity(socbridge_driver_to_ext_data_cmd); --- DEBUG GLOBAL BINDINGS --- -- synthesis translate_off - test <= ext_out_data_cmd; + test <= socbridge_driver_to_ext_data_cmd; -- synthesis translate_on --- TRANSLATOR --- @@ -309,13 +309,13 @@ begin end process comb_proc; -- Process updating internal registers based on primary clock - seq_proc: process(ext_in_rec.clk, rst, clk) + seq_proc: process(ext_to_socbridge_driver_rec.clk, rst, clk) begin if(rst = '1') then - st.ext_in_reg.data <= (others => '0'); - st.ext_out_reg.data <= (others => '0'); - st.ext_out_reg.clk <= '0'; - st.ext_out_reg.parity <= '1'; + st.ext_to_socbridge_driver_reg.data <= (others => '0'); + st.socbridge_driver_to_ext_reg.data <= (others => '0'); + st.socbridge_driver_to_ext_reg.clk <= '0'; + st.socbridge_driver_to_ext_reg.parity <= '1'; st.curr_state <= IDLE; st.write_stage <= 0; st.read_stage <= 0; @@ -323,13 +323,13 @@ begin st.curr_cmd_size <= 0; st.curr_addr <= (others => '0'); - elsif(rising_edge(ext_in_rec.clk)) then - st.ext_in_reg.data <= ext_in_rec.data; - st.ext_in_reg.clk <= ext_in_rec.clk; - st.ext_in_reg.parity <= ext_in_rec.parity; - st.ext_out_reg.data <= ext_out_data_cmd; - st.ext_out_reg.clk <= not st.ext_out_reg.clk; - st.ext_out_reg.parity <= next_parity_out; + elsif(rising_edge(ext_to_socbridge_driver_rec.clk)) then + st.ext_to_socbridge_driver_reg.data <= ext_to_socbridge_driver_rec.data; + st.ext_to_socbridge_driver_reg.clk <= ext_to_socbridge_driver_rec.clk; + st.ext_to_socbridge_driver_reg.parity <= ext_to_socbridge_driver_rec.parity; + st.socbridge_driver_to_ext_reg.data <= socbridge_driver_to_ext_data_cmd; + st.socbridge_driver_to_ext_reg.clk <= not st.socbridge_driver_to_ext_reg.clk; + st.socbridge_driver_to_ext_reg.parity <= next_parity_out; st.curr_state <= next_state; case st.curr_state is when IDLE => @@ -374,8 +374,8 @@ begin trans_st.curr_state <= trans_next_state; case trans_st.curr_state is when IDLE => - if ctrl_in.request = '1' then - trans_st.curr_inst <= ctrl_in; + if controller_to_socbridge_driver.request = '1' then + trans_st.curr_inst <= controller_to_socbridge_driver; else end if; trans_st.is_first_word <= '1'; @@ -395,6 +395,4 @@ begin end if; end process seq_proc; - - end architecture rtl; diff --git a/src/socbridge/socbridge_driver_tb.vhd b/src/socbridge/socbridge_driver_tb.vhd index 671c5e9..0471486 100644 --- a/src/socbridge/socbridge_driver_tb.vhd +++ b/src/socbridge/socbridge_driver_tb.vhd @@ -17,14 +17,14 @@ architecture tb of socbridge_driver_tb is signal cmd : command_t; signal address : std_logic_vector(31 downto 0); signal cmd_size : positive; - signal ext_in : ext_socbridge_in_t; - signal ext_out : ext_socbridge_out_t; - signal int_in : int_socbridge_in_t; - signal int_out : int_socbridge_out_t; - signal ctrl_in : controller_to_driver_t; - signal ctrl_out : driver_to_controller_t; - signal curr_word : std_logic_vector(ext_in.payload'length - 1 downto 0); - signal expected_out : std_logic_vector(ext_out.payload'length - 1 downto 0); + signal ext_to_socbridge_driver : ext_to_socbridge_driver_t; + signal socbridge_driver_to_ext : socbridge_driver_to_ext_t; + signal buffer_to_socbridge_driver : buffer_to_socbridge_driver_t; + signal socbridge_driver_to_buffer : socbridge_driver_to_buffer_t; + signal controller_to_socbridge_driver : controller_to_socbridge_driver_t; + signal socbridge_driver_controller : socbridge_driver_to_controller_t; + signal curr_word : std_logic_vector(ext_to_socbridge_driver.payload'length - 1 downto 0); + signal expected_out : std_logic_vector(socbridge_driver_to_ext.payload'length - 1 downto 0); constant CLK_PERIOD : TIME := 10 ns; constant SIMULATION_CYCLE_COUNT : INTEGER := 100; @@ -44,19 +44,19 @@ architecture tb of socbridge_driver_tb is end if; end procedure; - procedure check_data_out(correct_data: std_logic_vector(ext_out.payload'length - 1 downto 0)) is + procedure check_data_out(correct_data: std_logic_vector(socbridge_driver_to_ext.payload'length - 1 downto 0)) is begin - if(not (correct_data = ext_out.payload)) then - report "Data out is not what was expected, found " & to_string(ext_out.payload) + if(not (correct_data = socbridge_driver_to_ext.payload)) then + report "Data out is not what was expected, found " & to_string(socbridge_driver_to_ext.payload) & " but expected " & to_string(correct_data) severity error; fail("Data out"); end if; end procedure; - procedure check_parity(correct_data: std_logic_vector(ext_out.payload'length - 1 downto 0)) is + procedure check_parity(correct_data: std_logic_vector(socbridge_driver_to_ext.payload'length - 1 downto 0)) is begin - if(not (calc_parity(correct_data) = calc_parity(ext_out.payload))) then - report "Parity out is not what was expected, found " & std_logic'image(calc_parity(ext_out.payload)) + if(not (calc_parity(correct_data) = calc_parity(socbridge_driver_to_ext.payload))) then + report "Parity out is not what was expected, found " & std_logic'image(calc_parity(socbridge_driver_to_ext.payload)) & " but expected " & std_logic'image(calc_parity(correct_data)) severity error; fail("Parity out"); end if; @@ -69,10 +69,10 @@ architecture tb of socbridge_driver_tb is -- cmd : in command_t; -- address : in std_logic_vector(31 downto 0); -- cmd_size: in positive; --- ext_in : in ext_socbridge_in_t; --- ext_out : out ext_socbridge_out_t; --- int_in : out int_socbridge_in_t; --- int_out : in int_socbridge_out_t +-- ext_to_socbridge_driver : in ext_to_socbridge_driver_t; +-- socbridge_driver_to_ext : out socbridge_driver_to_ext_t; +-- buffer_to_socbridge_driver : out buffer_to_socbridge_driver_t; +-- socbridge_driver_to_buffer : in socbridge_driver_to_buffer_t -- ); -- end component socbridge_driver; @@ -81,15 +81,15 @@ begin port map( clk => clk, rst => rst, - ctrl_in => ctrl_in, - ctrl_out => ctrl_out, - ext_in => ext_in, - ext_out => ext_out, - int_in => int_in, - int_out => int_out + controller_to_socbridge_driver => controller_to_socbridge_driver, + socbridge_driver_to_controller => socbridge_driver_controller, + ext_to_socbridge_driver => ext_to_socbridge_driver, + socbridge_driver_to_ext => socbridge_driver_to_ext, + buffer_to_socbridge_driver => buffer_to_socbridge_driver, + socbridge_driver_to_buffer => socbridge_driver_to_buffer ); - ext_in.control(1) <= clk; + ext_to_socbridge_driver.control(1) <= clk; real_clk_proc: process begin for x in 0 to SIMULATION_CYCLE_COUNT*2 loop @@ -104,10 +104,10 @@ begin begin wait for CLK_PERIOD / 2; for x in 0 to SIMULATION_CYCLE_COUNT loop - if last_clk = ext_out.control(1) then + if last_clk = socbridge_driver_to_ext.control(1) then report "Secondary side clk not correct." severity error; end if; - last_clk := ext_out.control(1); + last_clk := socbridge_driver_to_ext.control(1); wait for CLK_PERIOD; end loop; wait; @@ -254,8 +254,8 @@ begin external_stimulus_signal: process(curr_word) begin - ext_in.payload <= curr_word; - ext_in.control(0) <= calc_parity(curr_word); + ext_to_socbridge_driver.payload <= curr_word; + ext_to_socbridge_driver.control(0) <= calc_parity(curr_word); end process external_stimulus_signal; external_stimulus: process @@ -299,30 +299,30 @@ begin internal_stimulus: process begin - int_in.is_full_in <= '0'; - int_in.write_enable_out <= '0'; + buffer_to_socbridge_driver.is_full_in <= '0'; + buffer_to_socbridge_driver.write_enable_out <= '0'; wait for 3 * CLK_PERIOD; -- stimulus goes here - int_in.write_enable_out <= '1'; - int_in.payload <= "00000001"; - wait until rising_edge(clk) and int_out.is_full_out = '0'; + buffer_to_socbridge_driver.write_enable_out <= '1'; + buffer_to_socbridge_driver.payload <= "00000001"; + wait until rising_edge(clk) and socbridge_driver_to_buffer.is_full_out = '0'; wait until falling_edge(clk); - int_in.payload <= "00000010"; - wait until rising_edge(clk) and int_out.is_full_out = '0'; + buffer_to_socbridge_driver.payload <= "00000010"; + wait until rising_edge(clk) and socbridge_driver_to_buffer.is_full_out = '0'; wait until falling_edge(clk); - int_in.payload <= "00000100"; - wait until rising_edge(clk) and int_out.is_full_out = '0'; + buffer_to_socbridge_driver.payload <= "00000100"; + wait until rising_edge(clk) and socbridge_driver_to_buffer.is_full_out = '0'; wait until falling_edge(clk); - int_in.payload <= "00001000"; - wait until rising_edge(clk) and int_out.is_full_out = '0'; + buffer_to_socbridge_driver.payload <= "00001000"; + wait until rising_edge(clk) and socbridge_driver_to_buffer.is_full_out = '0'; wait until falling_edge(clk); - int_in.payload <= "00010000"; - wait until int_out.is_full_out = '0'; + buffer_to_socbridge_driver.payload <= "00010000"; + wait until socbridge_driver_to_buffer.is_full_out = '0'; wait for CLK_PERIOD/2; wait until rising_edge(clk); wait until rising_edge(clk); - int_in.payload <= "00100000"; - wait until int_out.is_full_out = '0'; + buffer_to_socbridge_driver.payload <= "00100000"; + wait until socbridge_driver_to_buffer.is_full_out = '0'; wait for CLK_PERIOD/2; wait until rising_edge(clk); wait until rising_edge(clk); --- ??? Why all these rising_edge checks? diff --git a/src/socbridge/socbridge_driver_tb_pkg.vhd b/src/socbridge/socbridge_driver_tb_pkg.vhd index b8dee28..fc8e8cd 100644 --- a/src/socbridge/socbridge_driver_tb_pkg.vhd +++ b/src/socbridge/socbridge_driver_tb_pkg.vhd @@ -24,7 +24,7 @@ package socbridge_driver_tb_pkg is type translator_state_t is (IDLE, SEND, SEND_ACCEPTED, AWAIT); type translator_state_rec_t is record - curr_inst : controller_to_driver_t; + curr_inst : controller_to_socbridge_driver_t; curr_state : translator_state_t; is_first_word : std_logic; end record translator_state_rec_t; @@ -37,7 +37,7 @@ package socbridge_driver_tb_pkg is type state_rec_t is record curr_state: state_t; - ext_in_reg, ext_out_reg : ext_protocol_t; + ext_to_socbridge_driver_reg, socbridge_driver_to_ext_reg : ext_protocol_t; write_stage, read_stage : NATURAL; curr_cmd : command_t; curr_cmd_size: integer; @@ -56,8 +56,8 @@ package socbridge_driver_tb_pkg is --- DEBUG GLOBAL SIGNALS --- -- synthesis translate_off signal G_next_parity_out : std_logic; - signal G_ext_in_rec : ext_protocol_t; - signal G_ext_out_data_cmd : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); + signal G_ext_to_socbridge_driver_rec : ext_protocol_t; + signal G_socbridge_driver_to_ext_data_cmd : std_logic_vector(interface_inst.socbridge.payload_width - 1 downto 0); signal G_next_state : state_t; signal G_curr_command : command_t; signal G_curr_command_bits : std_logic_vector(4 downto 0);