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