diff --git a/src/controller/control_unit.vhd b/src/controller/control_unit.vhd index 8f68dad..44a108a 100644 --- a/src/controller/control_unit.vhd +++ b/src/controller/control_unit.vhd @@ -59,10 +59,13 @@ begin state.address <= manager_to_controller.address; state.seq_mem_access_count <= manager_to_controller.seq_mem_access_count; state.curr_driver <= manager_to_controller.driver_id(0); - with manager_to_controller.cmd select - state.instruction <= WRITE when "01", - READ when "10", - NO_OP when others; + if manager_to_controller.cmd = "01" then + state.instruction <= WRITE; + elsif manager_to_controller.cmd = "10" then + state.instruction <= READ; + else + state.instruction <= NO_OP; + end if; else state <= ((others => '0'), 0, diff --git a/src/ganimede/ganimede.vhd b/src/ganimede/ganimede.vhd index 7c09d91..a05f623 100644 --- a/src/ganimede/ganimede.vhd +++ b/src/ganimede/ganimede.vhd @@ -5,13 +5,13 @@ use gan_ganimede.io_types.all; library gan_socbridge; use gan_socbridge.socbridge_driver_pkg.all; library gan_controller; +library gan_manager; +use gan_manager.management_types.all; entity ganimede_toplevel is port ( clk : in std_logic; rst : in std_logic; - manager_to_ganimede : in manager_to_controller_t; - ganimede_to_manager : out controller_to_manager_t; ext_to_ganimede : in ext_to_ganimede_t; ganimede_to_ext : out ganimede_to_ext_t; ip_to_ganimede : in ip_to_ganimede_t; @@ -22,6 +22,10 @@ architecture rtl of ganimede_toplevel is --- SIGNAL DECLERATIONS --- signal drivers_to_controller : drivers_to_controller_t; signal controller_to_drivers : controller_to_drivers_t; + signal manager_to_controller : manager_to_controller_t; + 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 gan_socbridge_WE_in : std_logic; @@ -39,6 +43,8 @@ begin rst => rst, controller_to_socbridge_driver => controller_to_drivers.socbridge, socbridge_driver_to_controller => drivers_to_controller.socbridge, + manager_to_socbridge_driver => manager_to_socbridge_driver, + 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, @@ -49,11 +55,21 @@ begin port map( clk => clk, rst => rst, - manager_to_controller => manager_to_ganimede, - controller_to_manager => ganimede_to_manager, + manager_to_controller => manager_to_controller, + controller_to_manager => controller_to_manager, drivers_to_controller => drivers_to_controller, controller_to_drivers => controller_to_drivers - ); + ); + + manager_inst: entity gan_manager.management_unit + port map( + clk => clk, + rst => rst, + manager_to_controller => manager_to_controller, + controller_to_manager => controller_to_manager, + manager_to_socbridge_driver => manager_to_socbridge_driver, + socbridge_driver_to_manager => socbridge_driver_to_manager + ); --- LATER WE ADD OPTIMIZATIONS HERE --- diff --git a/src/ganimede/ganimede_tb.vhd b/src/ganimede/ganimede_tb.vhd index 243115c..52da0fe 100644 --- a/src/ganimede/ganimede_tb.vhd +++ b/src/ganimede/ganimede_tb.vhd @@ -12,6 +12,7 @@ end entity ganimede_tb; architecture tb of ganimede_tb is + signal done : boolean := false; constant CLK_PERIOD : Time := 10 ns; constant SIMULATION_CYCLE_COUNT : integer := 2000; signal clk, rst : std_logic := '0'; @@ -46,44 +47,9 @@ architecture tb of ganimede_tb is signal controller_to_manager: controller_to_manager_t; signal controller_to_drivers: controller_to_drivers_t; - signal curr_word : std_logic_vector(ext_to_ganimede.socbridge.payload'length - 1 downto 0); - signal expected_out : std_logic_vector(ganimede_to_ext.socbridge.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(ganimede_to_ext.socbridge.payload'length - 1 downto 0)) is - begin - if(not (correct_data = ganimede_to_ext.socbridge.payload)) then - report "Data out is not what was expected, found " & to_string(ganimede_to_ext.socbridge.payload) - & " but expected " & to_string(correct_data) severity error; - fail("Data out"); - end if; - end procedure; - - procedure check_parity(correct_data: std_logic_vector(ganimede_to_ext.socbridge.payload'length - 1 downto 0)) is - begin - if(not (calc_parity(correct_data) = calc_parity(ganimede_to_ext.socbridge.payload))) then - report "Parity out is not what was expected, found " & std_logic'image(calc_parity(ganimede_to_ext.socbridge.payload)) - & " but expected " & std_logic'image(calc_parity(correct_data)) severity error; - fail("Parity out"); - end if; - end procedure; begin - ganimede_inst: entity ganimede.ganimede_toplevel + ganimede_inst: entity gan_ganimede.ganimede_toplevel port map( clk => clk, rst => rst, @@ -96,101 +62,30 @@ begin ); ext_to_ganimede.socbridge.control(1) <= clk; - controller_clock_proc: process + real_clk_proc: process + variable cycle_count :integer := 0; begin - for i in 0 to SIMULATION_CYCLE_COUNT - 1 loop - wait for CLK_PERIOD / 2; - clk <= not clk; - end loop; - wait; - end process controller_clock_proc; + while (not done) and (cycle_count < MAX_CYCLE_COUNT) loop + clk <= not clk; + wait for CLK_PERIOD / 2; + end loop; + wait; + end process real_clk_proc; stimulus_proc: process begin report "Starting Simulation Stimulus!"; + done <= false; rst <= '1'; - manager_to_controller.address <= (others => '0'); - manager_to_controller.cmd <= "00"; - manager_to_controller.driver_id <= "1"; - manager_to_controller.seq_mem_access_count <= 256; wait for 3 * CLK_PERIOD; report "Reset grace period ended, starting stimulus..."; rst <= '0'; - manager_to_controller.address <= x"FA0FA0FA"; - manager_to_controller.cmd <= "01"; - wait until drivers_to_controller.socbridge.is_active = '1'; - report "Task received in driver, awaiting completion..."; - manager_to_controller.address <= (others => '0'); - manager_to_controller.cmd <= "00"; - wait until drivers_to_controller.socbridge.is_active = '0'; - wait for CLK_PERIOD; - report "Task completed in driver, sending next task..."; - manager_to_controller.address <= x"FA0FA0FA"; - manager_to_controller.cmd <= "10"; - wait for CLK_PERIOD; - wait until drivers_to_controller.socbridge.is_active = '1'; - report "Task received in driver, awaiting completion..."; - manager_to_controller.address <= (others => '0'); - manager_to_controller.cmd <= "00"; - wait until drivers_to_controller.socbridge.is_active = '0'; - wait for CLK_PERIOD; - report "Task completed in driver, ending simulation stimulus"; - manager_to_controller.address <= (others => '0'); - manager_to_controller.cmd <= "00"; - manager_to_controller.driver_id <= "0"; - manager_to_controller.seq_mem_access_count <= 0; + report "Test finished, ending simultaion..."; + done <= true; wait; end process stimulus_proc; - external_stimulus_signal: process(curr_word) - begin - ext_to_ganimede.socbridge.payload <= curr_word; - ext_to_ganimede.socbridge.control(0) <= calc_parity(curr_word); - end process external_stimulus_signal; - - external_stimulus: process - variable input : positive := 1; - 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 * 140; - curr_word <= "00101001"; - wait for CLK_PERIOD; - curr_word <= "00000000"; - wait for CLK_PERIOD * 140; - curr_word <= "00101001"; - 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; - internal_stimulus: process variable input : positive := 1; begin diff --git a/src/manager/management_unit.vhd b/src/manager/management_unit.vhd index acbabd1..5880885 100644 --- a/src/manager/management_unit.vhd +++ b/src/manager/management_unit.vhd @@ -27,17 +27,19 @@ architecture rtl of management_unit is signal word_address : natural; begin -word_address <= to_integer(shift_right(unsigned(socbridge_driver_to_manager.address), address_shift)); -read_address <= manager_state.memory(word_address); -write_address <= manager_state.memory(word_address); +read_address <= manager_state.memory(0); +write_address <= manager_state.memory(1); -comb_proc: process(controller_to_manager, socbridge_driver_to_manager) +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), address_shift)); -- Read data from manager to SoCBridge driver manager_to_socbridge_driver.ready <= '1'; - manager_to_socbridge_driver.data <= manager_state.memory(word_address); + manager_to_socbridge_driver.data <= manager_state.memory(local_word_address); manager_to_socbridge_driver.valid <= '1'; + word_address <= local_word_address; end process comb_proc; -- tre sorters sätt att avsluta en skrivning: diff --git a/src/socbridge/socbridge_driver.vhd b/src/socbridge/socbridge_driver.vhd index 3a9b790..4f6d28c 100644 --- a/src/socbridge/socbridge_driver.vhd +++ b/src/socbridge/socbridge_driver.vhd @@ -5,6 +5,8 @@ library gan_ganimede; use gan_ganimede.io_types.all; library gan_socbridge; use gan_socbridge.socbridge_driver_pkg.all; +library gan_manager; +use gan_manager.management_types.all; entity socbridge_driver is @@ -16,6 +18,8 @@ entity socbridge_driver is rst : in 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; + socbridge_driver_to_manager : out socbridge_driver_to_manager_t; ext_to_socbridge_driver : in ext_to_socbridge_driver_t; socbridge_driver_to_ext : out socbridge_driver_to_ext_t; ip_to_socbridge_driver : in ip_to_socbridge_driver_t; @@ -40,7 +44,6 @@ architecture rtl of socbridge_driver is --- FSM COMMUNICATION --- signal tx_sent_response, rx_received_response : std_logic; --- MANAGEMENT COMMUNICATION --- - signal mgnt_valid_in, mgnt_valid_out, mgnt_ready_out : std_logic; begin ext_to_socbridge_driver_rec.data <= ext_to_socbridge_driver.payload; ext_to_socbridge_driver_rec.clk <= ext_to_socbridge_driver.control(1); @@ -228,8 +231,7 @@ begin end if; when TX_R_BODY => if st.tx_stage > 0 then - socbridge_driver_to_ip.is_full_out <= '0'; - local_next_data_out := ip_to_socbridge_driver.payload; + local_next_data_out := st.curr_read_data(st.tx_stage * 8 - 1 downto (st.tx_stage - 1) * 8); end if; when TX_AWAIT => when ADDR1 => @@ -242,23 +244,23 @@ begin local_next_data_out := st.curr_tx_addr(7 downto 0); end case; --- ### RX_STATE BASED OUTPUT ### --- - mgnt_valid_in <= '0'; - mgnt_valid_out <= '0'; - mgnt_ready_out <= '0'; + socbridge_driver_to_manager.valid <= '0'; + socbridge_driver_to_manager.address <= (others => '0'); + socbridge_driver_to_manager.data <= (others => '0'); case st.curr_rx_state is when IDLE => when RX_HEADER => when RX_W_BODY => - -- TODO Add output signals to management unit later - -- TODO REPLACE TWO BELOW - socbridge_driver_to_ip.payload <= st.ext_to_socbridge_driver_reg.data; - socbridge_driver_to_ip.write_enable_in <= '1'; when RX_R_BODY => socbridge_driver_to_ip.payload <= st.ext_to_socbridge_driver_reg.data; socbridge_driver_to_ip.write_enable_in <= '1'; when RX_AWAIT => if st.curr_rx_transaction = WRITE or st.curr_rx_transaction = WRITE_ADD then - mgnt_valid_in <= '1'; + socbridge_driver_to_manager.data <= st.curr_write_data; + socbridge_driver_to_manager.address <= st.curr_rx_write_addr; + socbridge_driver_to_manager.valid <= '1'; + else + socbridge_driver_to_manager.address <= st.curr_rx_read_addr; end if; when ADDR1 => when ADDR2 => @@ -270,7 +272,10 @@ begin --- Next state assignment case trans_st.curr_state is when IDLE => - if trans_st.curr_inst.request = '1' then + if st.curr_rx_transaction = READ or st.curr_rx_transaction = READ_ADD + or st.curr_rx_transaction = WRITE or st.curr_rx_transaction = WRITE_ADD then + trans_next_state <= IDLE; + elsif trans_st.curr_inst.request = '1' then trans_next_state <= SEND; else trans_next_state <= IDLE; @@ -300,39 +305,40 @@ begin local_next_tx_transaction := NO_OP; next_tx_data_size <= 0; if trans_st.curr_state = IDLE and st.curr_rx_state = RX_AWAIT then - if st.curr_rx_transaction = WRITE or st.curr_rx_transaction = WRITE_ADD then + if (st.curr_rx_transaction = WRITE or st.curr_rx_transaction = WRITE_ADD) and manager_to_socbridge_driver.ready = '1' then local_next_tx_transaction := WRITE_ACK; - elsif st.curr_rx_transaction = READ or st.curr_rx_transaction = READ_ADD then + elsif (st.curr_rx_transaction = READ or st.curr_rx_transaction = READ_ADD) and manager_to_socbridge_driver.valid = '1' then next_tx_data_size <= st.rx_data_size; local_next_tx_transaction := READ_RESPONSE; end if; - end if; - 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 - local_next_tx_transaction := READ_ADD; - elsif trans_st.curr_inst.instruction = WRITE then - local_next_tx_transaction := WRITE_ADD; + else + 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 + local_next_tx_transaction := READ_ADD; + elsif trans_st.curr_inst.instruction = WRITE then + local_next_tx_transaction := WRITE_ADD; + end if; + else + if trans_st.curr_inst.instruction = READ then + local_next_tx_transaction := READ; + elsif trans_st.curr_inst.instruction = WRITE then + local_next_tx_transaction := WRITE; + end if; end if; - else - if trans_st.curr_inst.instruction = READ then - local_next_tx_transaction := READ; - elsif trans_st.curr_inst.instruction = WRITE then - local_next_tx_transaction := WRITE; - end if; - end if; - if trans_st.curr_inst.seq_mem_access_count > MAX_PKT_SIZE then - next_tx_data_size <= MAX_PKT_SIZE; - elsif trans_st.curr_inst.seq_mem_access_count > 0 then - next_tx_data_size <= trans_st.curr_inst.seq_mem_access_count; - else - next_tx_data_size <= 0; - end if; - when others => + if trans_st.curr_inst.seq_mem_access_count > MAX_PKT_SIZE then + next_tx_data_size <= MAX_PKT_SIZE; + elsif trans_st.curr_inst.seq_mem_access_count > 0 then + next_tx_data_size <= trans_st.curr_inst.seq_mem_access_count; + else + next_tx_data_size <= 0; + end if; + when others => end case; + end if; next_tx_transaction <= local_next_tx_transaction; next_rx_transaction <= local_next_rx_transaction; @@ -353,8 +359,10 @@ begin st.curr_tx_transaction <= NO_OP; st.curr_rx_transaction <= NO_OP; st.tx_data_size <= 0; + st.rx_data_size <= 0; st.curr_tx_addr <= (others => '0'); - st.curr_rx_addr <= (others => '0'); + st.curr_rx_read_addr <= (others => '0'); + st.curr_rx_write_addr <= (others => '0'); st.curr_write_data <= (others => '0'); st.curr_read_data <= (others => '0'); @@ -399,9 +407,6 @@ begin st.rx_stage <= 0; end if; when RX_HEADER => - if st.curr_rx_transaction = READ then - st.curr_rx_addr <= std_logic_vector(to_unsigned(to_integer(unsigned(st.curr_rx_addr) + 4), 32)); - end if; when RX_R_BODY => if st.rx_stage > 0 then st.rx_stage <= st.rx_stage - 1; @@ -411,14 +416,40 @@ begin st.rx_stage <= st.rx_stage - 1; st.curr_write_data((st.rx_stage) * 8 - 1 downto (st.rx_stage - 1) * 8) <= st.ext_to_socbridge_driver_reg.data; end if; + when RX_AWAIT => + st.curr_read_data <= manager_to_socbridge_driver.data; + -- THIS DOESN'T WORK, SHOULD BE FIXED BUT NOT NEEDED IF ONLY 4 BYTE ACCESSES ARRIVE + --if st.curr_tx_transaction = READ_RESPONSE or st.curr_tx_transaction = WRITE_ACK then + -- if st.curr_rx_transaction = READ or st.curr_rx_transaction = READ_ADD then + -- st.curr_rx_read_addr <= std_logic_vector(to_unsigned(to_integer(unsigned(st.curr_rx_read_addr) + 4), 32)); + -- elsif st.curr_rx_transaction = WRITE or st.curr_rx_transaction = WRITE_ADD then + -- st.curr_rx_write_addr <= std_logic_vector(to_unsigned(to_integer(unsigned(st.curr_rx_read_addr) + 4), 32)); + -- end if; + --end if; when ADDR1 => - st.curr_rx_addr(31 downto 24) <= st.ext_to_socbridge_driver_reg.data; + if st.curr_rx_transaction = READ_ADD then + st.curr_rx_read_addr(31 downto 24) <= st.ext_to_socbridge_driver_reg.data; + else + st.curr_rx_write_addr(31 downto 24) <= st.ext_to_socbridge_driver_reg.data; + end if; when ADDR2 => - st.curr_rx_addr(23 downto 16) <= st.ext_to_socbridge_driver_reg.data; + if st.curr_rx_transaction = READ_ADD then + st.curr_rx_read_addr(23 downto 16) <= st.ext_to_socbridge_driver_reg.data; + else + st.curr_rx_write_addr(23 downto 16) <= st.ext_to_socbridge_driver_reg.data; + end if; when ADDR3 => - st.curr_rx_addr(15 downto 8) <= st.ext_to_socbridge_driver_reg.data; + if st.curr_rx_transaction = READ_ADD then + st.curr_rx_read_addr(15 downto 8) <= st.ext_to_socbridge_driver_reg.data; + else + st.curr_rx_write_addr(15 downto 8) <= st.ext_to_socbridge_driver_reg.data; + end if; when ADDR4 => - st.curr_rx_addr(7 downto 0) <= st.ext_to_socbridge_driver_reg.data; + if st.curr_rx_transaction = READ_ADD then + st.curr_rx_read_addr(7 downto 0) <= st.ext_to_socbridge_driver_reg.data; + else + st.curr_rx_write_addr(7 downto 0) <= st.ext_to_socbridge_driver_reg.data; + end if; when others => end case; end if; diff --git a/src/socbridge/socbridge_driver_pkg.vhd b/src/socbridge/socbridge_driver_pkg.vhd index 7122115..deb3b06 100644 --- a/src/socbridge/socbridge_driver_pkg.vhd +++ b/src/socbridge/socbridge_driver_pkg.vhd @@ -45,7 +45,8 @@ package socbridge_driver_pkg is curr_write_data : std_logic_vector(31 downto 0); curr_read_data : std_logic_vector(31 downto 0); curr_tx_addr : std_logic_vector(31 downto 0); - curr_rx_addr : std_logic_vector(31 downto 0); + curr_rx_read_addr : std_logic_vector(31 downto 0); + curr_rx_write_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)