From 7994b9840488440b063309f6ecdb9e858a15205e Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Mon, 9 Aug 2021 06:44:43 +1000 Subject: [PATCH] Fix some whitespace issues Signed-off-by: Anton Blanchard --- core_debug.vhdl | 188 ++--- dmi_dtm_xilinx.vhdl | 250 +++--- fpga/clk_gen_ecp5.vhd | 174 ++-- fpga/clk_gen_mcmm.vhd | 100 +-- fpga/clk_gen_plle2.vhd | 152 ++-- fpga/main_bram.vhdl | 54 +- ppc_fx_insns.vhdl | 1550 ++++++++++++++++++------------------ sim_bram.vhdl | 66 +- wishbone_debug_master.vhdl | 184 ++--- xics.vhdl | 108 +-- 10 files changed, 1413 insertions(+), 1413 deletions(-) diff --git a/core_debug.vhdl b/core_debug.vhdl index a81f7e0..5bd7b62 100644 --- a/core_debug.vhdl +++ b/core_debug.vhdl @@ -12,25 +12,25 @@ entity core_debug is LOG_LENGTH : natural := 512 ); port ( - clk : in std_logic; - rst : in std_logic; - - dmi_addr : in std_ulogic_vector(3 downto 0); - dmi_din : in std_ulogic_vector(63 downto 0); - dmi_dout : out std_ulogic_vector(63 downto 0); - dmi_req : in std_ulogic; - dmi_wr : in std_ulogic; - dmi_ack : out std_ulogic; - - -- Debug actions - core_stop : out std_ulogic; - core_rst : out std_ulogic; - icache_rst : out std_ulogic; - - -- Core status inputs - terminate : in std_ulogic; - core_stopped : in std_ulogic; - nia : in std_ulogic_vector(63 downto 0); + clk : in std_logic; + rst : in std_logic; + + dmi_addr : in std_ulogic_vector(3 downto 0); + dmi_din : in std_ulogic_vector(63 downto 0); + dmi_dout : out std_ulogic_vector(63 downto 0); + dmi_req : in std_ulogic; + dmi_wr : in std_ulogic; + dmi_ack : out std_ulogic; + + -- Debug actions + core_stop : out std_ulogic; + core_rst : out std_ulogic; + icache_rst : out std_ulogic; + + -- Core status inputs + terminate : in std_ulogic; + core_stopped : in std_ulogic; + nia : in std_ulogic_vector(63 downto 0); msr : in std_ulogic_vector(63 downto 0); -- GSPR register read port @@ -45,8 +45,8 @@ entity core_debug is log_read_data : out std_ulogic_vector(63 downto 0); log_write_addr : out std_ulogic_vector(31 downto 0); - -- Misc - terminated_out : out std_ulogic + -- Misc + terminated_out : out std_ulogic ); end core_debug; @@ -60,7 +60,7 @@ architecture behave of core_debug is -- bit 2 : Icache reset -- bit 3 : Single step -- bit 4 : Core start - constant DBG_CORE_CTRL : std_ulogic_vector(3 downto 0) := "0000"; + constant DBG_CORE_CTRL : std_ulogic_vector(3 downto 0) := "0000"; constant DBG_CORE_CTRL_STOP : integer := 0; constant DBG_CORE_CTRL_RESET : integer := 1; constant DBG_CORE_CTRL_ICRESET : integer := 2; @@ -71,13 +71,13 @@ architecture behave of core_debug is -- bit 0 : Core stopping (wait til bit 1 set) -- bit 1 : Core stopped -- bit 2 : Core terminated (clears with start or reset) - constant DBG_CORE_STAT : std_ulogic_vector(3 downto 0) := "0001"; + constant DBG_CORE_STAT : std_ulogic_vector(3 downto 0) := "0001"; constant DBG_CORE_STAT_STOPPING : integer := 0; constant DBG_CORE_STAT_STOPPED : integer := 1; constant DBG_CORE_STAT_TERM : integer := 2; -- NIA register (read only for now) - constant DBG_CORE_NIA : std_ulogic_vector(3 downto 0) := "0010"; + constant DBG_CORE_NIA : std_ulogic_vector(3 downto 0) := "0010"; -- MSR (read only) constant DBG_CORE_MSR : std_ulogic_vector(3 downto 0) := "0011"; @@ -107,14 +107,14 @@ architecture behave of core_debug is signal do_gspr_rd : std_ulogic; signal gspr_index : gspr_index_t; - signal log_dmi_addr : std_ulogic_vector(31 downto 0) := (others => '0'); - signal log_dmi_data : std_ulogic_vector(63 downto 0) := (others => '0'); - signal log_dmi_trigger : std_ulogic_vector(63 downto 0) := (others => '0'); - signal do_log_trigger : std_ulogic := '0'; - signal do_dmi_log_rd : std_ulogic; - signal dmi_read_log_data : std_ulogic; + signal log_dmi_addr : std_ulogic_vector(31 downto 0) := (others => '0'); + signal log_dmi_data : std_ulogic_vector(63 downto 0) := (others => '0'); + signal log_dmi_trigger : std_ulogic_vector(63 downto 0) := (others => '0'); + signal do_log_trigger : std_ulogic := '0'; + signal do_dmi_log_rd : std_ulogic; + signal dmi_read_log_data : std_ulogic; signal dmi_read_log_data_1 : std_ulogic; - signal log_trigger_delay : integer range 0 to 255 := 0; + signal log_trigger_delay : integer range 0 to 255 := 0; begin -- Single cycle register accesses on DMI except for GSPR data @@ -125,36 +125,36 @@ begin -- Status register read composition stat_reg <= (2 => terminated, - 1 => core_stopped, - 0 => stopping, - others => '0'); + 1 => core_stopped, + 0 => stopping, + others => '0'); -- DMI read data mux with dmi_addr select dmi_dout <= - stat_reg when DBG_CORE_STAT, - nia when DBG_CORE_NIA, + stat_reg when DBG_CORE_STAT, + nia when DBG_CORE_NIA, msr when DBG_CORE_MSR, dbg_gpr_data when DBG_CORE_GSPR_DATA, log_write_addr & log_dmi_addr when DBG_CORE_LOG_ADDR, log_dmi_data when DBG_CORE_LOG_DATA, log_dmi_trigger when DBG_CORE_LOG_TRIGGER, - (others => '0') when others; + (others => '0') when others; -- DMI writes reg_write: process(clk) begin - if rising_edge(clk) then - -- Reset the 1-cycle "do" signals - do_step <= '0'; - do_reset <= '0'; - do_icreset <= '0'; + if rising_edge(clk) then + -- Reset the 1-cycle "do" signals + do_step <= '0'; + do_reset <= '0'; + do_icreset <= '0'; do_dmi_log_rd <= '0'; - if (rst) then - stopping <= '0'; - terminated <= '0'; + if (rst) then + stopping <= '0'; + terminated <= '0'; log_trigger_delay <= 0; - else + else if do_log_trigger = '1' or log_trigger_delay /= 0 then if log_trigger_delay = 255 then log_dmi_trigger(1) <= '1'; @@ -163,32 +163,32 @@ begin log_trigger_delay <= log_trigger_delay + 1; end if; end if; - -- Edge detect on dmi_req for 1-shot pulses - dmi_req_1 <= dmi_req; - if dmi_req = '1' and dmi_req_1 = '0' then - if dmi_wr = '1' then - report("DMI write to " & to_hstring(dmi_addr)); - - -- Control register actions - if dmi_addr = DBG_CORE_CTRL then - if dmi_din(DBG_CORE_CTRL_RESET) = '1' then - do_reset <= '1'; - terminated <= '0'; - end if; - if dmi_din(DBG_CORE_CTRL_STOP) = '1' then - stopping <= '1'; - end if; - if dmi_din(DBG_CORE_CTRL_STEP) = '1' then - do_step <= '1'; - terminated <= '0'; - end if; - if dmi_din(DBG_CORE_CTRL_ICRESET) = '1' then - do_icreset <= '1'; - end if; - if dmi_din(DBG_CORE_CTRL_START) = '1' then - stopping <= '0'; - terminated <= '0'; - end if; + -- Edge detect on dmi_req for 1-shot pulses + dmi_req_1 <= dmi_req; + if dmi_req = '1' and dmi_req_1 = '0' then + if dmi_wr = '1' then + report("DMI write to " & to_hstring(dmi_addr)); + + -- Control register actions + if dmi_addr = DBG_CORE_CTRL then + if dmi_din(DBG_CORE_CTRL_RESET) = '1' then + do_reset <= '1'; + terminated <= '0'; + end if; + if dmi_din(DBG_CORE_CTRL_STOP) = '1' then + stopping <= '1'; + end if; + if dmi_din(DBG_CORE_CTRL_STEP) = '1' then + do_step <= '1'; + terminated <= '0'; + end if; + if dmi_din(DBG_CORE_CTRL_ICRESET) = '1' then + do_icreset <= '1'; + end if; + if dmi_din(DBG_CORE_CTRL_START) = '1' then + stopping <= '0'; + terminated <= '0'; + end if; elsif dmi_addr = DBG_CORE_GSPR_INDEX then gspr_index <= dmi_din(gspr_index_t'left downto 0); elsif dmi_addr = DBG_CORE_LOG_ADDR then @@ -196,17 +196,17 @@ begin do_dmi_log_rd <= '1'; elsif dmi_addr = DBG_CORE_LOG_TRIGGER then log_dmi_trigger <= dmi_din; - end if; - else - report("DMI read from " & to_string(dmi_addr)); - end if; + end if; + else + report("DMI read from " & to_string(dmi_addr)); + end if; elsif dmi_read_log_data = '0' and dmi_read_log_data_1 = '1' then -- Increment log_dmi_addr after the end of a read from DBG_CORE_LOG_DATA log_dmi_addr(LOG_INDEX_BITS + 1 downto 0) <= std_ulogic_vector(unsigned(log_dmi_addr(LOG_INDEX_BITS+1 downto 0)) + 1); do_dmi_log_rd <= '1'; - end if; + end if; dmi_read_log_data_1 <= dmi_read_log_data; if dmi_req = '1' and dmi_addr = DBG_CORE_LOG_DATA then dmi_read_log_data <= '1'; @@ -214,15 +214,15 @@ begin dmi_read_log_data <= '0'; end if; - -- Set core stop on terminate. We'll be stopping some time *after* - -- the offending instruction, at least until we can do back flushes - -- that preserve NIA which we can't just yet. - if terminate = '1' then - stopping <= '1'; - terminated <= '1'; - end if; - end if; - end if; + -- Set core stop on terminate. We'll be stopping some time *after* + -- the offending instruction, at least until we can do back flushes + -- that preserve NIA which we can't just yet. + if terminate = '1' then + stopping <= '1'; + terminated <= '1'; + end if; + end if; + end if; end process; dbg_gpr_addr <= gspr_index; @@ -237,15 +237,15 @@ begin maybe_log: if LOG_LENGTH > 0 generate subtype log_ptr_t is unsigned(LOG_INDEX_BITS - 1 downto 0); type log_array_t is array(0 to LOG_LENGTH - 1) of std_ulogic_vector(255 downto 0); - signal log_array : log_array_t; - signal log_rd_ptr : log_ptr_t; - signal log_wr_ptr : log_ptr_t; - signal log_toggle : std_ulogic; - signal log_wr_enable : std_ulogic; + signal log_array : log_array_t; + signal log_rd_ptr : log_ptr_t; + signal log_wr_ptr : log_ptr_t; + signal log_toggle : std_ulogic; + signal log_wr_enable : std_ulogic; signal log_rd_ptr_latched : log_ptr_t; - signal log_rd : std_ulogic_vector(255 downto 0); - signal log_dmi_reading : std_ulogic; - signal log_dmi_read_done : std_ulogic; + signal log_rd : std_ulogic_vector(255 downto 0); + signal log_dmi_reading : std_ulogic; + signal log_dmi_read_done : std_ulogic; function select_dword(data : std_ulogic_vector(255 downto 0); addr : std_ulogic_vector(31 downto 0)) return std_ulogic_vector is diff --git a/dmi_dtm_xilinx.vhdl b/dmi_dtm_xilinx.vhdl index 69d8996..fcd4944 100644 --- a/dmi_dtm_xilinx.vhdl +++ b/dmi_dtm_xilinx.vhdl @@ -66,59 +66,59 @@ use unisim.vcomponents.all; entity dmi_dtm is generic(ABITS : INTEGER:=8; - DBITS : INTEGER:=32); - - port(sys_clk : in std_ulogic; - sys_reset : in std_ulogic; - dmi_addr : out std_ulogic_vector(ABITS - 1 downto 0); - dmi_din : in std_ulogic_vector(DBITS - 1 downto 0); - dmi_dout : out std_ulogic_vector(DBITS - 1 downto 0); - dmi_req : out std_ulogic; - dmi_wr : out std_ulogic; - dmi_ack : in std_ulogic --- dmi_err : in std_ulogic TODO: Add error response - ); + DBITS : INTEGER:=32); + + port(sys_clk : in std_ulogic; + sys_reset : in std_ulogic; + dmi_addr : out std_ulogic_vector(ABITS - 1 downto 0); + dmi_din : in std_ulogic_vector(DBITS - 1 downto 0); + dmi_dout : out std_ulogic_vector(DBITS - 1 downto 0); + dmi_req : out std_ulogic; + dmi_wr : out std_ulogic; + dmi_ack : in std_ulogic +-- dmi_err : in std_ulogic TODO: Add error response + ); end entity dmi_dtm; architecture behaviour of dmi_dtm is -- Signals coming out of the BSCANE2 block - signal jtag_reset : std_ulogic; - signal capture : std_ulogic; - signal update : std_ulogic; - signal drck : std_ulogic; - signal jtag_clk : std_ulogic; - signal sel : std_ulogic; - signal shift : std_ulogic; - signal tdi : std_ulogic; - signal tdo : std_ulogic; - signal tck : std_ulogic; + signal jtag_reset : std_ulogic; + signal capture : std_ulogic; + signal update : std_ulogic; + signal drck : std_ulogic; + signal jtag_clk : std_ulogic; + signal sel : std_ulogic; + signal shift : std_ulogic; + signal tdi : std_ulogic; + signal tdo : std_ulogic; + signal tck : std_ulogic; -- ** JTAG clock domain ** -- Shift register - signal shiftr : std_ulogic_vector(ABITS + DBITS + 1 downto 0); + signal shiftr : std_ulogic_vector(ABITS + DBITS + 1 downto 0); -- Latched request - signal request : std_ulogic_vector(ABITS + DBITS + 1 downto 0); + signal request : std_ulogic_vector(ABITS + DBITS + 1 downto 0); -- A request is present - signal jtag_req : std_ulogic; + signal jtag_req : std_ulogic; -- Synchronizer for jtag_rsp (sys clk -> jtag_clk) - signal dmi_ack_0 : std_ulogic; - signal dmi_ack_1 : std_ulogic; + signal dmi_ack_0 : std_ulogic; + signal dmi_ack_1 : std_ulogic; -- ** sys clock domain ** -- Synchronizer for jtag_req (jtag clk -> sys clk) - signal jtag_req_0 : std_ulogic; - signal jtag_req_1 : std_ulogic; + signal jtag_req_0 : std_ulogic; + signal jtag_req_1 : std_ulogic; -- ** combination signals - signal jtag_bsy : std_ulogic; - signal op_valid : std_ulogic; - signal rsp_op : std_ulogic_vector(1 downto 0); + signal jtag_bsy : std_ulogic; + signal op_valid : std_ulogic; + signal rsp_op : std_ulogic_vector(1 downto 0); -- ** Constants ** constant DMI_REQ_NOP : std_ulogic_vector(1 downto 0) := "00"; @@ -137,22 +137,22 @@ begin -- Implement the Xilinx bscan2 for series 7 devices (TODO: use PoC to -- wrap this if compatibility is required with older devices). bscan : BSCANE2 - generic map ( - JTAG_CHAIN => 2 - ) - port map ( - CAPTURE => capture, - DRCK => drck, - RESET => jtag_reset, - RUNTEST => open, - SEL => sel, - SHIFT => shift, - TCK => tck, - TDI => tdi, - TMS => open, - UPDATE => update, - TDO => tdo - ); + generic map ( + JTAG_CHAIN => 2 + ) + port map ( + CAPTURE => capture, + DRCK => drck, + RESET => jtag_reset, + RUNTEST => open, + SEL => sel, + SHIFT => shift, + TCK => tck, + TDI => tdi, + TMS => open, + UPDATE => update, + TDO => tdo + ); -- Some examples out there suggest buffering the clock so it's -- treated as a proper clock net. This is probably needed when using @@ -160,39 +160,39 @@ begin -- missing the update phase so maybe not... -- clkbuf : BUFG - port map ( --- I => drck, - I => tck, - O => jtag_clk - ); + port map ( +-- I => drck, + I => tck, + O => jtag_clk + ); -- dmi_req synchronization dmi_req_sync : process(sys_clk) begin - -- sys_reset is synchronous - if rising_edge(sys_clk) then - if (sys_reset = '1') then - jtag_req_0 <= '0'; - jtag_req_1 <= '0'; - else - jtag_req_0 <= jtag_req; - jtag_req_1 <= jtag_req_0; - end if; - end if; + -- sys_reset is synchronous + if rising_edge(sys_clk) then + if (sys_reset = '1') then + jtag_req_0 <= '0'; + jtag_req_1 <= '0'; + else + jtag_req_0 <= jtag_req; + jtag_req_1 <= jtag_req_0; + end if; + end if; end process; dmi_req <= jtag_req_1; -- dmi_ack synchronization dmi_ack_sync: process(jtag_clk, jtag_reset) begin - -- jtag_reset is async (see comments) - if jtag_reset = '1' then - dmi_ack_0 <= '0'; - dmi_ack_1 <= '0'; - elsif rising_edge(jtag_clk) then - dmi_ack_0 <= dmi_ack; - dmi_ack_1 <= dmi_ack_0; - end if; + -- jtag_reset is async (see comments) + if jtag_reset = '1' then + dmi_ack_0 <= '0'; + dmi_ack_1 <= '0'; + elsif rising_edge(jtag_clk) then + dmi_ack_0 <= dmi_ack; + dmi_ack_1 <= dmi_ack_0; + end if; end process; -- jtag_bsy indicates whether we can start a new request, we can when @@ -203,9 +203,9 @@ begin -- decode request type in shift register with shiftr(1 downto 0) select op_valid <= - '1' when DMI_REQ_RD, - '1' when DMI_REQ_WR, - '0' when others; + '1' when DMI_REQ_RD, + '1' when DMI_REQ_WR, + '0' when others; -- encode response op rsp_op <= DMI_RSP_BSY when jtag_bsy = '1' else DMI_RSP_OK; @@ -224,57 +224,57 @@ begin -- shifter: process(jtag_clk, jtag_reset, sys_reset) begin - if jtag_reset = '1' or sys_reset = '1' then - shiftr <= (others => '0'); - jtag_req <= '0'; - request <= (others => '0'); - elsif rising_edge(jtag_clk) then - - -- Handle jtag "commands" when sel is 1 - if sel = '1' then - -- Shift state, rotate the register - if shift = '1' then - shiftr <= tdi & shiftr(ABITS + DBITS + 1 downto 1); - end if; - - -- Update state (trigger) - -- - -- Latch the request if we aren't already processing one and - -- it has a valid command opcode. - -- - if update = '1' and op_valid = '1' then - if jtag_bsy = '0' then - request <= shiftr; - jtag_req <= '1'; - end if; - -- Set the shift register "op" to "busy". This will prevent - -- us from re-starting the command on the next update if - -- the command completes before that. - shiftr(1 downto 0) <= DMI_RSP_BSY; - end if; - - -- Request completion. - -- - -- Capture the response data for reads and clear request flag. - -- - -- Note: We clear req (and thus dmi_req) here which relies on tck - -- ticking and sel set. This means we are stuck with dmi_req up if - -- the jtag interface stops. Slaves must be resilient to this. - -- - if jtag_req = '1' and dmi_ack_1 = '1' then - jtag_req <= '0'; - if request(1 downto 0) = DMI_REQ_RD then - request(DBITS + 1 downto 2) <= dmi_din; - end if; - end if; - - -- Capture state, grab latch content with updated status - if capture = '1' then - shiftr <= request(ABITS + DBITS + 1 downto 2) & rsp_op; - end if; - - end if; - end if; + if jtag_reset = '1' or sys_reset = '1' then + shiftr <= (others => '0'); + jtag_req <= '0'; + request <= (others => '0'); + elsif rising_edge(jtag_clk) then + + -- Handle jtag "commands" when sel is 1 + if sel = '1' then + -- Shift state, rotate the register + if shift = '1' then + shiftr <= tdi & shiftr(ABITS + DBITS + 1 downto 1); + end if; + + -- Update state (trigger) + -- + -- Latch the request if we aren't already processing one and + -- it has a valid command opcode. + -- + if update = '1' and op_valid = '1' then + if jtag_bsy = '0' then + request <= shiftr; + jtag_req <= '1'; + end if; + -- Set the shift register "op" to "busy". This will prevent + -- us from re-starting the command on the next update if + -- the command completes before that. + shiftr(1 downto 0) <= DMI_RSP_BSY; + end if; + + -- Request completion. + -- + -- Capture the response data for reads and clear request flag. + -- + -- Note: We clear req (and thus dmi_req) here which relies on tck + -- ticking and sel set. This means we are stuck with dmi_req up if + -- the jtag interface stops. Slaves must be resilient to this. + -- + if jtag_req = '1' and dmi_ack_1 = '1' then + jtag_req <= '0'; + if request(1 downto 0) = DMI_REQ_RD then + request(DBITS + 1 downto 2) <= dmi_din; + end if; + end if; + + -- Capture state, grab latch content with updated status + if capture = '1' then + shiftr <= request(ABITS + DBITS + 1 downto 2) & rsp_op; + end if; + + end if; + end if; end process; end architecture behaviour; diff --git a/fpga/clk_gen_ecp5.vhd b/fpga/clk_gen_ecp5.vhd index a71fa75..7b0f40a 100644 --- a/fpga/clk_gen_ecp5.vhd +++ b/fpga/clk_gen_ecp5.vhd @@ -8,11 +8,11 @@ entity clock_generator is ); port ( - ext_clk : in std_logic; - pll_rst_in : in std_logic; - pll_clk_out : out std_logic; - pll_locked_out : out std_logic - ); + ext_clk : in std_logic; + pll_rst_in : in std_logic; + pll_clk_out : out std_logic; + pll_locked_out : out std_logic + ); end entity clock_generator; @@ -20,66 +20,66 @@ architecture bypass of clock_generator is -- prototype of ECP5 PLL component EHXPLLL is - generic ( - CLKI_DIV : integer := 1; - CLKFB_DIV : integer := 1; - CLKOP_DIV : integer := 8; - CLKOS_DIV : integer := 8; - CLKOS2_DIV : integer := 8; - CLKOS3_DIV : integer := 8; - CLKOP_ENABLE : string := "ENABLED"; - CLKOS_ENABLE : string := "DISABLED"; - CLKOS2_ENABLE : string := "DISABLED"; - CLKOS3_ENABLE : string := "DISABLED"; - CLKOP_CPHASE : integer := 0; - CLKOS_CPHASE : integer := 0; - CLKOS2_CPHASE : integer := 0; - CLKOS3_CPHASE : integer := 0; - CLKOP_FPHASE : integer := 0; - CLKOS_FPHASE : integer := 0; - CLKOS2_FPHASE : integer := 0; - CLKOS3_FPHASE : integer := 0; - FEEDBK_PATH : string := "CLKOP"; - CLKOP_TRIM_POL : string := "RISING"; - CLKOP_TRIM_DELAY : integer := 0; - CLKOS_TRIM_POL : string := "RISING"; - CLKOS_TRIM_DELAY : integer := 0; - OUTDIVIDER_MUXA : string := "DIVA"; - OUTDIVIDER_MUXB : string := "DIVB"; - OUTDIVIDER_MUXC : string := "DIVC"; - OUTDIVIDER_MUXD : string := "DIVD"; - PLL_LOCK_MODE : integer := 0; - PLL_LOCK_DELAY : integer := 200; - STDBY_ENABLE : string := "DISABLED"; - REFIN_RESET : string := "DISABLED"; - SYNC_ENABLE : string := "DISABLED"; - INT_LOCK_STICKY : string := "ENABLED"; - DPHASE_SOURCE : string := "DISABLED"; - PLLRST_ENA : string := "DISABLED"; - INTFB_WAKE : string := "DISABLED" ); - port ( - CLKI : in std_logic; - CLKFB : in std_logic; - PHASESEL1 : in std_logic; - PHASESEL0 : in std_logic; - PHASEDIR : in std_logic; - PHASESTEP : in std_logic; - PHASELOADREG : in std_logic; - STDBY : in std_logic; - PLLWAKESYNC : in std_logic; - RST : in std_logic; - ENCLKOP : in std_logic; - ENCLKOS : in std_logic; - ENCLKOS2 : in std_logic; - ENCLKOS3 : in std_logic; - CLKOP : out std_logic; - CLKOS : out std_logic; - CLKOS2 : out std_logic; - CLKOS3 : out std_logic; - LOCK : out std_logic; - INTLOCK : out std_logic; - REFCLK : out std_logic; - CLKINTFB : out std_logic ); + generic ( + CLKI_DIV : integer := 1; + CLKFB_DIV : integer := 1; + CLKOP_DIV : integer := 8; + CLKOS_DIV : integer := 8; + CLKOS2_DIV : integer := 8; + CLKOS3_DIV : integer := 8; + CLKOP_ENABLE : string := "ENABLED"; + CLKOS_ENABLE : string := "DISABLED"; + CLKOS2_ENABLE : string := "DISABLED"; + CLKOS3_ENABLE : string := "DISABLED"; + CLKOP_CPHASE : integer := 0; + CLKOS_CPHASE : integer := 0; + CLKOS2_CPHASE : integer := 0; + CLKOS3_CPHASE : integer := 0; + CLKOP_FPHASE : integer := 0; + CLKOS_FPHASE : integer := 0; + CLKOS2_FPHASE : integer := 0; + CLKOS3_FPHASE : integer := 0; + FEEDBK_PATH : string := "CLKOP"; + CLKOP_TRIM_POL : string := "RISING"; + CLKOP_TRIM_DELAY : integer := 0; + CLKOS_TRIM_POL : string := "RISING"; + CLKOS_TRIM_DELAY : integer := 0; + OUTDIVIDER_MUXA : string := "DIVA"; + OUTDIVIDER_MUXB : string := "DIVB"; + OUTDIVIDER_MUXC : string := "DIVC"; + OUTDIVIDER_MUXD : string := "DIVD"; + PLL_LOCK_MODE : integer := 0; + PLL_LOCK_DELAY : integer := 200; + STDBY_ENABLE : string := "DISABLED"; + REFIN_RESET : string := "DISABLED"; + SYNC_ENABLE : string := "DISABLED"; + INT_LOCK_STICKY : string := "ENABLED"; + DPHASE_SOURCE : string := "DISABLED"; + PLLRST_ENA : string := "DISABLED"; + INTFB_WAKE : string := "DISABLED" ); + port ( + CLKI : in std_logic; + CLKFB : in std_logic; + PHASESEL1 : in std_logic; + PHASESEL0 : in std_logic; + PHASEDIR : in std_logic; + PHASESTEP : in std_logic; + PHASELOADREG : in std_logic; + STDBY : in std_logic; + PLLWAKESYNC : in std_logic; + RST : in std_logic; + ENCLKOP : in std_logic; + ENCLKOS : in std_logic; + ENCLKOS2 : in std_logic; + ENCLKOS3 : in std_logic; + CLKOP : out std_logic; + CLKOS : out std_logic; + CLKOS2 : out std_logic; + CLKOS3 : out std_logic; + LOCK : out std_logic; + INTLOCK : out std_logic; + REFCLK : out std_logic; + CLKINTFB : out std_logic ); end component; signal clkop : std_logic; @@ -99,29 +99,29 @@ begin pll_locked_out <= not lock; -- FIXME: EHXPLLL lock signal active low?!? clkgen: EHXPLLL - generic map( - CLKOP_CPHASE => 11, -- FIXME: Copied from prjtrells. + generic map( + CLKOP_CPHASE => 11, -- FIXME: Copied from prjtrells. CLKOP_DIV => PLL_CLKOP_DIV, - CLKFB_DIV => PLL_CLKFB_DIV, - CLKI_DIV => PLL_CLKI_DIV - ) - port map ( - CLKI => ext_clk, - CLKOP => clkop, - CLKFB => clkop, - LOCK => lock, - RST => pll_rst_in, - PHASESEL1 => '0', - PHASESEL0 => '0', - PHASEDIR => '0', - PHASESTEP => '0', - PHASELOADREG => '0', - STDBY => '0', - PLLWAKESYNC => '0', - ENCLKOP => '0', - ENCLKOS => '0', - ENCLKOS2 => '0', - ENCLKOS3 => '0' + CLKFB_DIV => PLL_CLKFB_DIV, + CLKI_DIV => PLL_CLKI_DIV + ) + port map ( + CLKI => ext_clk, + CLKOP => clkop, + CLKFB => clkop, + LOCK => lock, + RST => pll_rst_in, + PHASESEL1 => '0', + PHASESEL0 => '0', + PHASEDIR => '0', + PHASESTEP => '0', + PHASELOADREG => '0', + STDBY => '0', + PLLWAKESYNC => '0', + ENCLKOP => '0', + ENCLKOS => '0', + ENCLKOS2 => '0', + ENCLKOS3 => '0' ); end architecture bypass; diff --git a/fpga/clk_gen_mcmm.vhd b/fpga/clk_gen_mcmm.vhd index 08db930..2906901 100644 --- a/fpga/clk_gen_mcmm.vhd +++ b/fpga/clk_gen_mcmm.vhd @@ -8,7 +8,7 @@ entity clock_generator is generic ( CLK_INPUT_HZ : positive := 12000000; CLK_OUTPUT_HZ : positive := 50000000 - ); + ); port ( ext_clk : in std_logic; pll_rst_in : in std_logic; @@ -24,66 +24,66 @@ architecture rtl of clock_generator is clkfbout_mult : real range 2.0 to 64.0; clkout_divide : real range 1.0 to 128.0; divclk_divide : integer range 1 to 106; - force_rst : std_ulogic; + force_rst : std_ulogic; end record; function gen_pll_settings ( constant input_hz : positive; - constant output_hz : positive) + constant output_hz : positive) return pll_settings_t is - constant bad_settings : pll_settings_t := - (clkin_period => 0.0, - clkfbout_mult => 2.0, - clkout_divide => 1.0, - divclk_divide => 1, - force_rst => '1'); + constant bad_settings : pll_settings_t := + (clkin_period => 0.0, + clkfbout_mult => 2.0, + clkout_divide => 1.0, + divclk_divide => 1, + force_rst => '1'); begin case input_hz is - when 100000000 => - case output_hz is - when 100000000 => - return (clkin_period => 10.0, - clkfbout_mult => 16.0, - clkout_divide => 16.0, - divclk_divide => 1, - force_rst => '0'); - when 50000000 => - return (clkin_period => 10.0, - clkfbout_mult => 16.0, - clkout_divide => 32.0, - divclk_divide => 1, - force_rst => '0'); - when others => - report "Unsupported output frequency" severity failure; - return bad_settings; - end case; - when 12000000 => - case output_hz is - when 100000000 => - return (clkin_period => 83.33, - clkfbout_mult => 50.0, - clkout_divide => 6.0, - divclk_divide => 1, - force_rst => '0'); - when 50000000 => - return (clkin_period => 83.33, - clkfbout_mult => 50.0, - clkout_divide => 12.0, - divclk_divide => 1, - force_rst => '0'); - when others => - report "Unsupported output frequency" severity failure; - return bad_settings; - end case; - when others => - report "Unsupported input frequency" severity failure; - return bad_settings; + when 100000000 => + case output_hz is + when 100000000 => + return (clkin_period => 10.0, + clkfbout_mult => 16.0, + clkout_divide => 16.0, + divclk_divide => 1, + force_rst => '0'); + when 50000000 => + return (clkin_period => 10.0, + clkfbout_mult => 16.0, + clkout_divide => 32.0, + divclk_divide => 1, + force_rst => '0'); + when others => + report "Unsupported output frequency" severity failure; + return bad_settings; + end case; + when 12000000 => + case output_hz is + when 100000000 => + return (clkin_period => 83.33, + clkfbout_mult => 50.0, + clkout_divide => 6.0, + divclk_divide => 1, + force_rst => '0'); + when 50000000 => + return (clkin_period => 83.33, + clkfbout_mult => 50.0, + clkout_divide => 12.0, + divclk_divide => 1, + force_rst => '0'); + when others => + report "Unsupported output frequency" severity failure; + return bad_settings; + end case; + when others => + report "Unsupported input frequency" severity failure; + return bad_settings; end case; end function gen_pll_settings; constant pll_settings : pll_settings_t := gen_pll_settings(clk_input_hz, - clk_output_hz); + clk_output_hz); begin pll : MMCME2_BASE generic map ( @@ -111,6 +111,6 @@ begin CLKFBIN => clkfb, CLKIN1 => ext_clk, PWRDWN => '0', - RST => pll_rst_in or pll_settings.force_rst + RST => pll_rst_in or pll_settings.force_rst ); end architecture rtl; diff --git a/fpga/clk_gen_plle2.vhd b/fpga/clk_gen_plle2.vhd index dfe2ed9..b336d6f 100644 --- a/fpga/clk_gen_plle2.vhd +++ b/fpga/clk_gen_plle2.vhd @@ -6,100 +6,100 @@ use UNISIM.vcomponents.all; entity clock_generator is generic ( - CLK_INPUT_HZ : positive := 100000000; - CLK_OUTPUT_HZ : positive := 100000000 - ); + CLK_INPUT_HZ : positive := 100000000; + CLK_OUTPUT_HZ : positive := 100000000 + ); port ( - ext_clk : in std_logic; - pll_rst_in : in std_logic; - pll_clk_out : out std_logic; - pll_locked_out : out std_logic); + ext_clk : in std_logic; + pll_rst_in : in std_logic; + pll_clk_out : out std_logic; + pll_locked_out : out std_logic); end entity clock_generator; architecture rtl of clock_generator is signal clkfb : std_ulogic; type pll_settings_t is record - clkin_period : real range 0.000 to 52.631; - clkfbout_mult : integer range 2 to 64; - clkout_divide : integer range 1 to 128; - divclk_divide : integer range 1 to 56; - force_rst : std_ulogic; + clkin_period : real range 0.000 to 52.631; + clkfbout_mult : integer range 2 to 64; + clkout_divide : integer range 1 to 128; + divclk_divide : integer range 1 to 56; + force_rst : std_ulogic; end record; function gen_pll_settings ( constant input_hz : positive; - constant output_hz : positive) - return pll_settings_t is + constant output_hz : positive) + return pll_settings_t is - constant bad_settings : pll_settings_t := - (clkin_period => 0.0, - clkfbout_mult => 2, - clkout_divide => 1, - divclk_divide => 1, - force_rst => '1'); + constant bad_settings : pll_settings_t := + (clkin_period => 0.0, + clkfbout_mult => 2, + clkout_divide => 1, + divclk_divide => 1, + force_rst => '1'); begin - case input_hz is - when 200000000 => - case output_hz is - when 100000000 => - return (clkin_period => 5.0, - clkfbout_mult => 8, - clkout_divide => 16, - divclk_divide => 1, - force_rst => '0'); - when others => - report "Unsupported output frequency" severity failure; - return bad_settings; - end case; - when 100000000 => - case output_hz is - when 100000000 => - return (clkin_period => 10.0, - clkfbout_mult => 16, - clkout_divide => 16, - divclk_divide => 1, - force_rst => '0'); - when 50000000 => - return (clkin_period => 10.0, - clkfbout_mult => 16, - clkout_divide => 32, - divclk_divide => 1, - force_rst => '0'); - when others => - report "Unsupported output frequency" severity failure; - return bad_settings; - end case; - when others => - report "Unsupported input frequency" severity failure; - return bad_settings; - end case; + case input_hz is + when 200000000 => + case output_hz is + when 100000000 => + return (clkin_period => 5.0, + clkfbout_mult => 8, + clkout_divide => 16, + divclk_divide => 1, + force_rst => '0'); + when others => + report "Unsupported output frequency" severity failure; + return bad_settings; + end case; + when 100000000 => + case output_hz is + when 100000000 => + return (clkin_period => 10.0, + clkfbout_mult => 16, + clkout_divide => 16, + divclk_divide => 1, + force_rst => '0'); + when 50000000 => + return (clkin_period => 10.0, + clkfbout_mult => 16, + clkout_divide => 32, + divclk_divide => 1, + force_rst => '0'); + when others => + report "Unsupported output frequency" severity failure; + return bad_settings; + end case; + when others => + report "Unsupported input frequency" severity failure; + return bad_settings; + end case; end function gen_pll_settings; constant pll_settings : pll_settings_t := gen_pll_settings(clk_input_hz, - clk_output_hz); + clk_output_hz); begin pll : PLLE2_BASE - generic map ( - BANDWIDTH => "OPTIMIZED", - CLKFBOUT_MULT => pll_settings.clkfbout_mult, - CLKIN1_PERIOD => pll_settings.clkin_period, - CLKOUT0_DIVIDE => pll_settings.clkout_divide, - DIVCLK_DIVIDE => pll_settings.divclk_divide, - STARTUP_WAIT => "FALSE") - port map ( - CLKOUT0 => pll_clk_out, - CLKOUT1 => open, - CLKOUT2 => open, - CLKOUT3 => open, - CLKOUT4 => open, - CLKOUT5 => open, - CLKFBOUT => clkfb, - LOCKED => pll_locked_out, - CLKIN1 => ext_clk, - PWRDWN => '0', - RST => pll_rst_in or pll_settings.force_rst, - CLKFBIN => clkfb); + generic map ( + BANDWIDTH => "OPTIMIZED", + CLKFBOUT_MULT => pll_settings.clkfbout_mult, + CLKIN1_PERIOD => pll_settings.clkin_period, + CLKOUT0_DIVIDE => pll_settings.clkout_divide, + DIVCLK_DIVIDE => pll_settings.divclk_divide, + STARTUP_WAIT => "FALSE") + port map ( + CLKOUT0 => pll_clk_out, + CLKOUT1 => open, + CLKOUT2 => open, + CLKOUT3 => open, + CLKOUT4 => open, + CLKOUT5 => open, + CLKFBOUT => clkfb, + LOCKED => pll_locked_out, + CLKIN1 => ext_clk, + PWRDWN => '0', + RST => pll_rst_in or pll_settings.force_rst, + CLKFBIN => clkfb); end architecture rtl; diff --git a/fpga/main_bram.vhdl b/fpga/main_bram.vhdl index fcc3701..ebdb0bd 100644 --- a/fpga/main_bram.vhdl +++ b/fpga/main_bram.vhdl @@ -9,20 +9,20 @@ library work; entity main_bram is generic( - WIDTH : natural := 64; - HEIGHT_BITS : natural := 1024; - MEMORY_SIZE : natural := 65536; - RAM_INIT_FILE : string - ); + WIDTH : natural := 64; + HEIGHT_BITS : natural := 1024; + MEMORY_SIZE : natural := 65536; + RAM_INIT_FILE : string + ); port( - clk : in std_logic; - addr : in std_logic_vector(HEIGHT_BITS - 1 downto 0) ; - di : in std_logic_vector(WIDTH-1 downto 0); - do : out std_logic_vector(WIDTH-1 downto 0); - sel : in std_logic_vector((WIDTH/8)-1 downto 0); - re : in std_ulogic; - we : in std_ulogic - ); + clk : in std_logic; + addr : in std_logic_vector(HEIGHT_BITS - 1 downto 0) ; + di : in std_logic_vector(WIDTH-1 downto 0); + do : out std_logic_vector(WIDTH-1 downto 0); + sel : in std_logic_vector((WIDTH/8)-1 downto 0); + re : in std_ulogic; + we : in std_ulogic + ); end entity main_bram; architecture behaviour of main_bram is @@ -63,20 +63,20 @@ begin -- Actual RAM template memory_0: process(clk) begin - if rising_edge(clk) then - if we = '1' then - for i in 0 to 7 loop - if sel(i) = '1' then - memory(to_integer(unsigned(addr)))((i + 1) * 8 - 1 downto i * 8) <= - di((i + 1) * 8 - 1 downto i * 8); - end if; - end loop; - end if; - if re = '1' then - obuf <= memory(to_integer(unsigned(addr))); - end if; - do <= obuf; - end if; + if rising_edge(clk) then + if we = '1' then + for i in 0 to 7 loop + if sel(i) = '1' then + memory(to_integer(unsigned(addr)))((i + 1) * 8 - 1 downto i * 8) <= + di((i + 1) * 8 - 1 downto i * 8); + end if; + end loop; + end if; + if re = '1' then + obuf <= memory(to_integer(unsigned(addr))); + end if; + do <= obuf; + end if; end process; end architecture behaviour; diff --git a/ppc_fx_insns.vhdl b/ppc_fx_insns.vhdl index c34a884..7509e0d 100644 --- a/ppc_fx_insns.vhdl +++ b/ppc_fx_insns.vhdl @@ -6,747 +6,747 @@ library work; use work.helpers.all; package ppc_fx_insns is - function ppc_addi (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; - function ppc_addis (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; - function ppc_add (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_subf (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_neg (ra: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - - function ppc_addic (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; - function ppc_adde (ra, rb: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector; - function ppc_subfic (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; - function ppc_subfc (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_subfe (ra, rb: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector; - function ppc_addze (ra: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector; - - function ppc_andi (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; - function ppc_andis (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; - function ppc_ori (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; - function ppc_oris (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; - function ppc_xori (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; - function ppc_xoris (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; - function ppc_and (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_xor (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_nand (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_or (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_nor (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_andc (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_eqv (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_orc (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - - function ppc_extsb (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_extsh (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_extsw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - - function ppc_cntlzw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_cnttzw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_cntlzd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_cnttzd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - - function ppc_popcntb (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_popcntw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_popcntd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - - function ppc_prtyd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_prtyw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - - function ppc_rlwinm (rs: std_ulogic_vector(63 downto 0); sh, mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector; - function ppc_rlwnm (rs, rb: std_ulogic_vector(63 downto 0); mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector; - function ppc_rlwimi (ra, rs: std_ulogic_vector(63 downto 0); sh, mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector; - function ppc_rldicl (rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector; - function ppc_rldicr (rs: std_ulogic_vector(63 downto 0); sh, me: std_ulogic_vector(5 downto 0)) return std_ulogic_vector; - function ppc_rldic (rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector; - function ppc_rldcl (rs, rb: std_ulogic_vector(63 downto 0); mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector; - function ppc_rldcr (rs, rb: std_ulogic_vector(63 downto 0); me: std_ulogic_vector(5 downto 0)) return std_ulogic_vector; - function ppc_rldimi (ra, rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector; - - function ppc_slw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_srw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_srawi (rs : std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector; - function ppc_sraw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_sld (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_srd (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_sradi (rs: std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector; - function ppc_srad (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - - function ppc_mulld (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_mulhd (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_mulhdu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_mulli (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; - function ppc_mullw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_mulhw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_mulhwu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - - function ppc_cmpi (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0); + function ppc_addi (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; + function ppc_addis (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; + function ppc_add (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_subf (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_neg (ra: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + + function ppc_addic (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; + function ppc_adde (ra, rb: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector; + function ppc_subfic (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; + function ppc_subfc (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_subfe (ra, rb: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector; + function ppc_addze (ra: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector; + + function ppc_andi (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; + function ppc_andis (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; + function ppc_ori (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; + function ppc_oris (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; + function ppc_xori (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; + function ppc_xoris (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; + function ppc_and (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_xor (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_nand (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_or (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_nor (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_andc (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_eqv (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_orc (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + + function ppc_extsb (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_extsh (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_extsw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + + function ppc_cntlzw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_cnttzw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_cntlzd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_cnttzd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + + function ppc_popcntb (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_popcntw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_popcntd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + + function ppc_prtyd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_prtyw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + + function ppc_rlwinm (rs: std_ulogic_vector(63 downto 0); sh, mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector; + function ppc_rlwnm (rs, rb: std_ulogic_vector(63 downto 0); mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector; + function ppc_rlwimi (ra, rs: std_ulogic_vector(63 downto 0); sh, mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector; + function ppc_rldicl (rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector; + function ppc_rldicr (rs: std_ulogic_vector(63 downto 0); sh, me: std_ulogic_vector(5 downto 0)) return std_ulogic_vector; + function ppc_rldic (rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector; + function ppc_rldcl (rs, rb: std_ulogic_vector(63 downto 0); mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector; + function ppc_rldcr (rs, rb: std_ulogic_vector(63 downto 0); me: std_ulogic_vector(5 downto 0)) return std_ulogic_vector; + function ppc_rldimi (ra, rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector; + + function ppc_slw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_srw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_srawi (rs : std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector; + function ppc_sraw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_sld (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_srd (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_sradi (rs: std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector; + function ppc_srad (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + + function ppc_mulld (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_mulhd (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_mulhdu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_mulli (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector; + function ppc_mullw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_mulhw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_mulhwu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + + function ppc_cmpi (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0); so: std_ulogic) return std_ulogic_vector; - function ppc_cmp (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0); + function ppc_cmp (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0); so: std_ulogic) return std_ulogic_vector; - function ppc_cmpli (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0); + function ppc_cmpli (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0); so: std_ulogic) return std_ulogic_vector; - function ppc_cmpl (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0); + function ppc_cmpl (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0); so: std_ulogic) return std_ulogic_vector; - function ppc_cmpb (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_cmpb (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; function ppc_cmpeqb (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; function ppc_cmprb (ra, rb: std_ulogic_vector(63 downto 0); l: std_ulogic) return std_ulogic_vector; - function ppc_divw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_divdu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_divd (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_divwu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_divw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_divdu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_divd (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; + function ppc_divwu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector; - function ppc_bc_taken(bo, bi: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0); ctr: std_ulogic_vector(63 downto 0)) return std_ulogic; + function ppc_bc_taken(bo, bi: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0); ctr: std_ulogic_vector(63 downto 0)) return std_ulogic; end package ppc_fx_insns; package body ppc_fx_insns is - function ppc_addi (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is - begin - return std_ulogic_vector(signed(ra) + signed(si)); - end; - - function ppc_addic (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is - begin - return std_logic_vector(resize(unsigned(ra), 65) + unsigned(resize(signed(si), 64))); - end; - - function ppc_adde (ra, rb: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector is - begin - return std_logic_vector(resize(unsigned(ra), 65) + resize(unsigned(rb), 65) + carry); - end; - - function ppc_subfic (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is - begin - return std_logic_vector(unsigned(resize(signed(si), 64)) + resize(unsigned(not(ra)), 65) + 1); - end; - - function ppc_subfc (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return std_logic_vector(resize(unsigned(rb), 65) + resize(unsigned(not(ra)), 65) + 1); - end; - - function ppc_subfe (ra, rb: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector is - begin - return std_logic_vector(resize(unsigned(rb), 65) + resize(unsigned(not(ra)), 65) + carry); - end; - - function ppc_addze (ra: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector is - begin - return std_logic_vector(resize(unsigned(ra), 65) + carry); - end; - - function ppc_addis (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is - begin - return std_ulogic_vector(signed(ra) + shift_left(resize(signed(si), 32), 16)); - end; - - function ppc_add (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return std_ulogic_vector(signed(ra) + signed(rb)); - end; - - function ppc_subf (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return std_ulogic_vector(signed(rb) - signed(ra)); - end; - - function ppc_neg (ra: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return std_ulogic_vector(-signed(ra)); - end; - - function ppc_andi (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is - begin - return rs and std_ulogic_vector(resize(unsigned(ui), 64)); - end; - - function ppc_andis (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is - begin - return rs and std_ulogic_vector(shift_left(resize(unsigned(ui), 64), 16)); - end; - - function ppc_ori (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is - begin - return rs or std_ulogic_vector(resize(unsigned(ui), 64)); - end; - - function ppc_oris (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is - begin - return rs or std_ulogic_vector(shift_left(resize(unsigned(ui), 64), 16)); - end; - - function ppc_xori (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is - begin - return rs xor std_ulogic_vector(resize(unsigned(ui), 64)); - end; - - function ppc_xoris (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is - begin - return rs xor std_ulogic_vector(shift_left(resize(unsigned(ui), 64), 16)); - end; - - function ppc_and (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return rs and rb; - end; - - function ppc_xor (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return rs xor rb; - end; - - function ppc_nand (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return rs nand rb; - end; - - function ppc_or (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return rs or rb; - end; - - function ppc_nor (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return rs nor rb; - end; - - function ppc_andc (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return rs and not(rb); - end; - - function ppc_eqv (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return not(rs xor rb); - end; - - function ppc_orc (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return rs or not(rb); - end; - - function ppc_extsb (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return std_ulogic_vector(resize(signed(rs(7 downto 0)), rs'length)); - end; - - function ppc_extsh (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return std_ulogic_vector(resize(signed(rs(15 downto 0)), rs'length)); - end; - - function ppc_extsw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return std_ulogic_vector(resize(signed(rs(31 downto 0)), rs'length)); - end; - - function ppc_cntlzw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return std_ulogic_vector(to_unsigned(fls_32(rs(31 downto 0)), rs'length)); - end; - - function ppc_cnttzw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return std_ulogic_vector(to_unsigned(ffs_32(rs(31 downto 0)), rs'length)); - end; - - function ppc_cntlzd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return std_ulogic_vector(to_unsigned(fls_64(rs), rs'length)); - end; - - function ppc_cnttzd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return std_ulogic_vector(to_unsigned(ffs_64(rs), rs'length)); - end; - - function ppc_popcntb (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable ret: std_ulogic_vector (rs'range); - variable hi: integer; - variable lo: integer; - begin - ret := (others => '0'); - - for i in 1 to 8 loop - hi := (8*i)-1; - lo := 8*(i-1); - ret(hi downto lo) := popcnt8(rs(hi downto lo)); - end loop; - - return ret; - end; - - function ppc_popcntw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable ret: std_ulogic_vector (rs'range); - variable hi: integer; - variable lo: integer; - begin - ret := (others => '0'); - - for i in 1 to 2 loop - hi := (32*i)-1; - lo := 32*(i-1); - ret(hi downto lo) := popcnt32(rs(hi downto lo)); - end loop; - - return ret; - end; - - function ppc_popcntd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return popcnt64(rs); - end; - - function ppc_prtyd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable tmp : std_ulogic; - variable ret : std_ulogic_vector(63 downto 0); - begin - ret := (others => '0'); - - tmp := '0'; - for i in 0 to 7 loop - tmp := tmp xor rs(i*8); - end loop; - - ret(0) := tmp; - return ret; - end; - - function ppc_prtyw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable tmp : std_ulogic; - variable ret : std_ulogic_vector(63 downto 0); - begin - ret := (others => '0'); - - tmp := '0'; - for i in 0 to 3 loop - tmp := tmp xor rs(i*8); - end loop; - ret(0) := tmp; - - tmp := '0'; - for i in 4 to 7 loop - tmp := tmp xor rs(i*8); - end loop; - ret(32) := tmp; - - return ret; - end; - - function ppc_rlwinm (rs: std_ulogic_vector(63 downto 0); sh, mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector is - variable hi, lo : integer; - variable tmp1, tmp2 : std_ulogic_vector(63 downto 0); - begin - hi := 31 - to_integer(unsigned(mb)); - lo := 31 - to_integer(unsigned(me)); - tmp1 := rs(31 downto 0) & rs(31 downto 0); - tmp1 := std_ulogic_vector(rotate_left(unsigned(tmp1), to_integer(unsigned(sh)))); - tmp2 := (others => '0'); - if hi < lo then - -- Mask wraps around - for i in 0 to 63 loop - if i <= hi or i >= lo then - tmp2(i) := tmp1(i); - end if; - end loop; - else - for i in 0 to 63 loop - if i >= lo and i <= hi then - tmp2(i) := tmp1(i); - end if; - end loop; - end if; - return tmp2; - end; - - function ppc_rlwnm (rs, rb: std_ulogic_vector(63 downto 0); mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector is - variable hi, lo : integer; - variable tmp1, tmp2 : std_ulogic_vector(63 downto 0); - variable n : integer; - begin - hi := 31 - to_integer(unsigned(mb)); - lo := 31 - to_integer(unsigned(me)); - n := to_integer(unsigned(rb(4 downto 0))); - tmp1 := rs(31 downto 0) & rs(31 downto 0); - tmp1 := std_ulogic_vector(rotate_left(unsigned(tmp1), n)); - tmp2 := (others => '0'); - if hi < lo then - -- Mask wraps around - for i in 0 to 63 loop - if i <= hi or i >= lo then - tmp2(i) := tmp1(i); - end if; - end loop; - else - for i in 0 to 63 loop - if i >= lo and i <= hi then - tmp2(i) := tmp1(i); - end if; - end loop; - end if; - return tmp2; - end; - - function ppc_rlwimi (ra, rs: std_ulogic_vector(63 downto 0); sh, mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector is - variable hi, lo : integer; - variable tmp1, tmp2 : std_ulogic_vector(63 downto 0); - begin - hi := 31 - to_integer(unsigned(mb)); - lo := 31 - to_integer(unsigned(me)); - tmp1 := rs(31 downto 0) & rs(31 downto 0); - tmp1 := std_ulogic_vector(rotate_left(unsigned(tmp1), to_integer(unsigned(sh)))); - tmp2 := ra; - if hi < lo then - -- Mask wraps around - for i in 0 to 63 loop - if i <= hi or i >= lo then - tmp2(i) := tmp1(i); - end if; - end loop; - else - for i in 0 to 63 loop - if i >= lo and i <= hi then - tmp2(i) := tmp1(i); - end if; - end loop; - end if; - return tmp2; - end; - - function ppc_rldicl (rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is - variable hi : integer; - variable tmp1, tmp2 : std_ulogic_vector(63 downto 0); - begin - hi := 63-to_integer(unsigned(mb)); - tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(sh)))); - tmp2 := (others => '0'); - for i in 0 to 63 loop - if i <= hi then - tmp2(i) := tmp1(i); - end if; - end loop; - return tmp2; - end; - - function ppc_rldicr (rs: std_ulogic_vector(63 downto 0); sh, me: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is - variable lo : integer; - variable tmp1, tmp2 : std_ulogic_vector(63 downto 0); - begin - lo := 63-to_integer(unsigned(me)); - tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(sh)))); - tmp2 := (others => '0'); - for i in 0 to 63 loop - if i >= lo then - tmp2(i) := tmp1(i); - end if; - end loop; - return tmp2; - end; - - function ppc_rldic (rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is - variable hi, lo : integer; - variable tmp1, tmp2 : std_ulogic_vector(63 downto 0); - begin - hi := 63-to_integer(unsigned(mb)); - lo := to_integer(unsigned(sh)); - tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(sh)))); - tmp2 := (others => '0'); - if hi < lo then - -- Mask wraps around - for i in 0 to 63 loop - if i <= hi or i >= lo then - tmp2(i) := tmp1(i); - end if; - end loop; - else - for i in 0 to 63 loop - if i >= lo and i <= hi then - tmp2(i) := tmp1(i); - end if; - end loop; - end if; - return tmp2; - end; - - function ppc_rldcl (rs, rb: std_ulogic_vector(63 downto 0); mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is - variable hi : integer; - variable tmp1, tmp2 : std_ulogic_vector(63 downto 0); - begin - hi := 63-to_integer(unsigned(mb)); - tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(rb(5 downto 0))))); - tmp2 := (others => '0'); - for i in 0 to 63 loop - if i <= hi then - tmp2(i) := tmp1(i); - end if; - end loop; - return tmp2; - end; - - function ppc_rldcr (rs, rb: std_ulogic_vector(63 downto 0); me: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is - variable lo : integer; - variable tmp1, tmp2 : std_ulogic_vector(63 downto 0); - begin - lo := 63-to_integer(unsigned(me)); - tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(rb(5 downto 0))))); - tmp2 := (others => '0'); - for i in 0 to 63 loop - if i >= lo then - tmp2(i) := tmp1(i); - end if; - end loop; - return tmp2; - end; - - function ppc_rldimi (ra, rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is - variable hi, lo : integer; - variable tmp1, tmp2 : std_ulogic_vector(rs'range); - begin - hi := 63-to_integer(unsigned(mb)); - lo := to_integer(unsigned(sh)); - tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), lo)); - tmp2 := ra; - if hi < lo then - -- Mask wraps around - for i in 0 to 63 loop - if i <= hi or i >= lo then - tmp2(i) := tmp1(i); - end if; - end loop; - else - for i in 0 to 63 loop - if i >= lo and i <= hi then - tmp2(i) := tmp1(i); - end if; - end loop; - end if; - return tmp2; - end; - - function ppc_slw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable n : integer; - variable tmp : unsigned(31 downto 0); - begin - n := to_integer(unsigned(rb(5 downto 0))); - tmp := shift_left(unsigned(rs(31 downto 0)), n); - - return (63 downto 32 => '0') & std_ulogic_vector(tmp); - end; - - function ppc_srw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable n : integer; - variable tmp : unsigned(31 downto 0); - begin - n := to_integer(unsigned(rb(5 downto 0))); - tmp := shift_right(unsigned(rs(31 downto 0)), n); - - return (63 downto 32 => '0') & std_ulogic_vector(tmp); - end; - - function ppc_srawi (rs : std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is - variable n : integer; - variable tmp : signed(31 downto 0); - variable mask : std_ulogic_vector(63 downto 0); - variable carry: std_ulogic; - begin - n := to_integer(unsigned(sh)); - tmp := shift_right(signed(rs(31 downto 0)), n); - -- what about n = 0? - mask := (others => '0'); - for i in 0 to 63 loop - if i < n then - mask(i) := '1'; - end if; - end loop; - carry := '0' when (rs and mask) = (63 downto 0 => '0') else rs(31); - - return carry & std_ulogic_vector(resize(tmp, rs'length)); - end; - - function ppc_sraw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable n : natural; - variable tmp : signed(31 downto 0); - variable mask : std_ulogic_vector(63 downto 0); - variable carry: std_ulogic; - begin - n := to_integer(unsigned(rb(5 downto 0))); - tmp := shift_right(signed(rs(31 downto 0)), n); - -- what about n = 0? - mask := (others => '0'); - for i in 0 to 63 loop - if i < n then - mask(i) := '1'; - end if; - end loop; - carry := or (rs and mask) and rs(31); - return carry & std_ulogic_vector(resize(tmp, rs'length)); - end; - - function ppc_sld (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable n : integer; - begin - n := to_integer(unsigned(rb(6 downto 0))); - return std_ulogic_vector(shift_left(unsigned(rs), n)); - end; - - function ppc_srd (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable n : integer; - begin - n := to_integer(unsigned(rb(6 downto 0))); - return std_ulogic_vector(shift_right(unsigned(rs), n)); - end; - - function ppc_sradi (rs: std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is - variable n : integer; - variable carry: std_ulogic; - variable mask : std_ulogic_vector(63 downto 0); - begin - n := to_integer(unsigned(sh)); - -- what about n = 0? - mask := (others => '0'); - for i in 0 to 63 loop - if i < n then - mask(i) := '1'; - end if; - end loop; - carry := '0' when (rs and mask) = (63 downto 0 => '0') else rs(63); - - return carry & std_ulogic_vector(shift_right(signed(rs), n)); - end; - - function ppc_srad (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable n : integer; - variable carry: std_ulogic; - variable mask : std_ulogic_vector(63 downto 0); - begin - n := to_integer(unsigned(rb(6 downto 0))); - -- what about n = 0? - mask := (others => '0'); - for i in 0 to 63 loop - if i < n then - mask(i) := '1'; - end if; - end loop; - carry := '0' when (rs and mask) = (63 downto 0 => '0') else rs(63); - - return carry & std_ulogic_vector(shift_right(signed(rs), n)); - end; - - -- Not sure how to better communicate the top 64 bits of the result is unused - function ppc_mulld (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable tmp: signed(127 downto 0); - begin - tmp := signed(ra) * signed(rb); - return std_ulogic_vector(tmp(63 downto 0)); - end; - - -- Not sure how to better communicate the top 64 bits of the result is unused - function ppc_mulhd (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable tmp: signed(127 downto 0); - begin - tmp := signed(ra) * signed(rb); - return std_ulogic_vector(tmp(127 downto 64)); - end; - - -- Not sure how to better communicate the top 64 bits of the result is unused - function ppc_mulhdu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable tmp: unsigned(127 downto 0); - begin - tmp := unsigned(ra) * unsigned(rb); - return std_ulogic_vector(tmp(127 downto 64)); - end; - - -- Not sure how to better communicate the top 16 bits of the result is unused - function ppc_mulli (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is - variable tmp: signed(79 downto 0); - begin - tmp := signed(ra) * signed(si); - return std_ulogic_vector(tmp(63 downto 0)); - end; - - function ppc_mullw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - begin - return std_ulogic_vector(signed(ra(31 downto 0)) * signed(rb(31 downto 0))); - end; - - function ppc_mulhw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable tmp: signed(63 downto 0); - begin - tmp := signed(ra(31 downto 0)) * signed(rb(31 downto 0)); - return std_ulogic_vector(tmp(63 downto 32)) & std_ulogic_vector(tmp(63 downto 32)); - end; - - function ppc_mulhwu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable tmp: unsigned(63 downto 0); - begin - tmp := unsigned(ra(31 downto 0)) * unsigned(rb(31 downto 0)); - return std_ulogic_vector(tmp(63 downto 32)) & std_ulogic_vector(tmp(63 downto 32)); - end; - - function ppc_cmpi (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0); + function ppc_addi (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is + begin + return std_ulogic_vector(signed(ra) + signed(si)); + end; + + function ppc_addic (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is + begin + return std_logic_vector(resize(unsigned(ra), 65) + unsigned(resize(signed(si), 64))); + end; + + function ppc_adde (ra, rb: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector is + begin + return std_logic_vector(resize(unsigned(ra), 65) + resize(unsigned(rb), 65) + carry); + end; + + function ppc_subfic (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is + begin + return std_logic_vector(unsigned(resize(signed(si), 64)) + resize(unsigned(not(ra)), 65) + 1); + end; + + function ppc_subfc (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return std_logic_vector(resize(unsigned(rb), 65) + resize(unsigned(not(ra)), 65) + 1); + end; + + function ppc_subfe (ra, rb: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector is + begin + return std_logic_vector(resize(unsigned(rb), 65) + resize(unsigned(not(ra)), 65) + carry); + end; + + function ppc_addze (ra: std_ulogic_vector(63 downto 0); carry: std_ulogic) return std_ulogic_vector is + begin + return std_logic_vector(resize(unsigned(ra), 65) + carry); + end; + + function ppc_addis (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is + begin + return std_ulogic_vector(signed(ra) + shift_left(resize(signed(si), 32), 16)); + end; + + function ppc_add (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return std_ulogic_vector(signed(ra) + signed(rb)); + end; + + function ppc_subf (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return std_ulogic_vector(signed(rb) - signed(ra)); + end; + + function ppc_neg (ra: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return std_ulogic_vector(-signed(ra)); + end; + + function ppc_andi (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is + begin + return rs and std_ulogic_vector(resize(unsigned(ui), 64)); + end; + + function ppc_andis (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is + begin + return rs and std_ulogic_vector(shift_left(resize(unsigned(ui), 64), 16)); + end; + + function ppc_ori (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is + begin + return rs or std_ulogic_vector(resize(unsigned(ui), 64)); + end; + + function ppc_oris (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is + begin + return rs or std_ulogic_vector(shift_left(resize(unsigned(ui), 64), 16)); + end; + + function ppc_xori (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is + begin + return rs xor std_ulogic_vector(resize(unsigned(ui), 64)); + end; + + function ppc_xoris (rs: std_ulogic_vector(63 downto 0); ui: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is + begin + return rs xor std_ulogic_vector(shift_left(resize(unsigned(ui), 64), 16)); + end; + + function ppc_and (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return rs and rb; + end; + + function ppc_xor (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return rs xor rb; + end; + + function ppc_nand (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return rs nand rb; + end; + + function ppc_or (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return rs or rb; + end; + + function ppc_nor (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return rs nor rb; + end; + + function ppc_andc (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return rs and not(rb); + end; + + function ppc_eqv (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return not(rs xor rb); + end; + + function ppc_orc (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return rs or not(rb); + end; + + function ppc_extsb (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return std_ulogic_vector(resize(signed(rs(7 downto 0)), rs'length)); + end; + + function ppc_extsh (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return std_ulogic_vector(resize(signed(rs(15 downto 0)), rs'length)); + end; + + function ppc_extsw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return std_ulogic_vector(resize(signed(rs(31 downto 0)), rs'length)); + end; + + function ppc_cntlzw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return std_ulogic_vector(to_unsigned(fls_32(rs(31 downto 0)), rs'length)); + end; + + function ppc_cnttzw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return std_ulogic_vector(to_unsigned(ffs_32(rs(31 downto 0)), rs'length)); + end; + + function ppc_cntlzd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return std_ulogic_vector(to_unsigned(fls_64(rs), rs'length)); + end; + + function ppc_cnttzd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return std_ulogic_vector(to_unsigned(ffs_64(rs), rs'length)); + end; + + function ppc_popcntb (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable ret: std_ulogic_vector (rs'range); + variable hi: integer; + variable lo: integer; + begin + ret := (others => '0'); + + for i in 1 to 8 loop + hi := (8*i)-1; + lo := 8*(i-1); + ret(hi downto lo) := popcnt8(rs(hi downto lo)); + end loop; + + return ret; + end; + + function ppc_popcntw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable ret: std_ulogic_vector (rs'range); + variable hi: integer; + variable lo: integer; + begin + ret := (others => '0'); + + for i in 1 to 2 loop + hi := (32*i)-1; + lo := 32*(i-1); + ret(hi downto lo) := popcnt32(rs(hi downto lo)); + end loop; + + return ret; + end; + + function ppc_popcntd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return popcnt64(rs); + end; + + function ppc_prtyd (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable tmp : std_ulogic; + variable ret : std_ulogic_vector(63 downto 0); + begin + ret := (others => '0'); + + tmp := '0'; + for i in 0 to 7 loop + tmp := tmp xor rs(i*8); + end loop; + + ret(0) := tmp; + return ret; + end; + + function ppc_prtyw (rs: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable tmp : std_ulogic; + variable ret : std_ulogic_vector(63 downto 0); + begin + ret := (others => '0'); + + tmp := '0'; + for i in 0 to 3 loop + tmp := tmp xor rs(i*8); + end loop; + ret(0) := tmp; + + tmp := '0'; + for i in 4 to 7 loop + tmp := tmp xor rs(i*8); + end loop; + ret(32) := tmp; + + return ret; + end; + + function ppc_rlwinm (rs: std_ulogic_vector(63 downto 0); sh, mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector is + variable hi, lo : integer; + variable tmp1, tmp2 : std_ulogic_vector(63 downto 0); + begin + hi := 31 - to_integer(unsigned(mb)); + lo := 31 - to_integer(unsigned(me)); + tmp1 := rs(31 downto 0) & rs(31 downto 0); + tmp1 := std_ulogic_vector(rotate_left(unsigned(tmp1), to_integer(unsigned(sh)))); + tmp2 := (others => '0'); + if hi < lo then + -- Mask wraps around + for i in 0 to 63 loop + if i <= hi or i >= lo then + tmp2(i) := tmp1(i); + end if; + end loop; + else + for i in 0 to 63 loop + if i >= lo and i <= hi then + tmp2(i) := tmp1(i); + end if; + end loop; + end if; + return tmp2; + end; + + function ppc_rlwnm (rs, rb: std_ulogic_vector(63 downto 0); mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector is + variable hi, lo : integer; + variable tmp1, tmp2 : std_ulogic_vector(63 downto 0); + variable n : integer; + begin + hi := 31 - to_integer(unsigned(mb)); + lo := 31 - to_integer(unsigned(me)); + n := to_integer(unsigned(rb(4 downto 0))); + tmp1 := rs(31 downto 0) & rs(31 downto 0); + tmp1 := std_ulogic_vector(rotate_left(unsigned(tmp1), n)); + tmp2 := (others => '0'); + if hi < lo then + -- Mask wraps around + for i in 0 to 63 loop + if i <= hi or i >= lo then + tmp2(i) := tmp1(i); + end if; + end loop; + else + for i in 0 to 63 loop + if i >= lo and i <= hi then + tmp2(i) := tmp1(i); + end if; + end loop; + end if; + return tmp2; + end; + + function ppc_rlwimi (ra, rs: std_ulogic_vector(63 downto 0); sh, mb, me: std_ulogic_vector(4 downto 0)) return std_ulogic_vector is + variable hi, lo : integer; + variable tmp1, tmp2 : std_ulogic_vector(63 downto 0); + begin + hi := 31 - to_integer(unsigned(mb)); + lo := 31 - to_integer(unsigned(me)); + tmp1 := rs(31 downto 0) & rs(31 downto 0); + tmp1 := std_ulogic_vector(rotate_left(unsigned(tmp1), to_integer(unsigned(sh)))); + tmp2 := ra; + if hi < lo then + -- Mask wraps around + for i in 0 to 63 loop + if i <= hi or i >= lo then + tmp2(i) := tmp1(i); + end if; + end loop; + else + for i in 0 to 63 loop + if i >= lo and i <= hi then + tmp2(i) := tmp1(i); + end if; + end loop; + end if; + return tmp2; + end; + + function ppc_rldicl (rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is + variable hi : integer; + variable tmp1, tmp2 : std_ulogic_vector(63 downto 0); + begin + hi := 63-to_integer(unsigned(mb)); + tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(sh)))); + tmp2 := (others => '0'); + for i in 0 to 63 loop + if i <= hi then + tmp2(i) := tmp1(i); + end if; + end loop; + return tmp2; + end; + + function ppc_rldicr (rs: std_ulogic_vector(63 downto 0); sh, me: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is + variable lo : integer; + variable tmp1, tmp2 : std_ulogic_vector(63 downto 0); + begin + lo := 63-to_integer(unsigned(me)); + tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(sh)))); + tmp2 := (others => '0'); + for i in 0 to 63 loop + if i >= lo then + tmp2(i) := tmp1(i); + end if; + end loop; + return tmp2; + end; + + function ppc_rldic (rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is + variable hi, lo : integer; + variable tmp1, tmp2 : std_ulogic_vector(63 downto 0); + begin + hi := 63-to_integer(unsigned(mb)); + lo := to_integer(unsigned(sh)); + tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(sh)))); + tmp2 := (others => '0'); + if hi < lo then + -- Mask wraps around + for i in 0 to 63 loop + if i <= hi or i >= lo then + tmp2(i) := tmp1(i); + end if; + end loop; + else + for i in 0 to 63 loop + if i >= lo and i <= hi then + tmp2(i) := tmp1(i); + end if; + end loop; + end if; + return tmp2; + end; + + function ppc_rldcl (rs, rb: std_ulogic_vector(63 downto 0); mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is + variable hi : integer; + variable tmp1, tmp2 : std_ulogic_vector(63 downto 0); + begin + hi := 63-to_integer(unsigned(mb)); + tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(rb(5 downto 0))))); + tmp2 := (others => '0'); + for i in 0 to 63 loop + if i <= hi then + tmp2(i) := tmp1(i); + end if; + end loop; + return tmp2; + end; + + function ppc_rldcr (rs, rb: std_ulogic_vector(63 downto 0); me: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is + variable lo : integer; + variable tmp1, tmp2 : std_ulogic_vector(63 downto 0); + begin + lo := 63-to_integer(unsigned(me)); + tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), to_integer(unsigned(rb(5 downto 0))))); + tmp2 := (others => '0'); + for i in 0 to 63 loop + if i >= lo then + tmp2(i) := tmp1(i); + end if; + end loop; + return tmp2; + end; + + function ppc_rldimi (ra, rs: std_ulogic_vector(63 downto 0); sh, mb: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is + variable hi, lo : integer; + variable tmp1, tmp2 : std_ulogic_vector(rs'range); + begin + hi := 63-to_integer(unsigned(mb)); + lo := to_integer(unsigned(sh)); + tmp1 := std_ulogic_vector(rotate_left(unsigned(rs), lo)); + tmp2 := ra; + if hi < lo then + -- Mask wraps around + for i in 0 to 63 loop + if i <= hi or i >= lo then + tmp2(i) := tmp1(i); + end if; + end loop; + else + for i in 0 to 63 loop + if i >= lo and i <= hi then + tmp2(i) := tmp1(i); + end if; + end loop; + end if; + return tmp2; + end; + + function ppc_slw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable n : integer; + variable tmp : unsigned(31 downto 0); + begin + n := to_integer(unsigned(rb(5 downto 0))); + tmp := shift_left(unsigned(rs(31 downto 0)), n); + + return (63 downto 32 => '0') & std_ulogic_vector(tmp); + end; + + function ppc_srw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable n : integer; + variable tmp : unsigned(31 downto 0); + begin + n := to_integer(unsigned(rb(5 downto 0))); + tmp := shift_right(unsigned(rs(31 downto 0)), n); + + return (63 downto 32 => '0') & std_ulogic_vector(tmp); + end; + + function ppc_srawi (rs : std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is + variable n : integer; + variable tmp : signed(31 downto 0); + variable mask : std_ulogic_vector(63 downto 0); + variable carry: std_ulogic; + begin + n := to_integer(unsigned(sh)); + tmp := shift_right(signed(rs(31 downto 0)), n); + -- what about n = 0? + mask := (others => '0'); + for i in 0 to 63 loop + if i < n then + mask(i) := '1'; + end if; + end loop; + carry := '0' when (rs and mask) = (63 downto 0 => '0') else rs(31); + + return carry & std_ulogic_vector(resize(tmp, rs'length)); + end; + + function ppc_sraw (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable n : natural; + variable tmp : signed(31 downto 0); + variable mask : std_ulogic_vector(63 downto 0); + variable carry: std_ulogic; + begin + n := to_integer(unsigned(rb(5 downto 0))); + tmp := shift_right(signed(rs(31 downto 0)), n); + -- what about n = 0? + mask := (others => '0'); + for i in 0 to 63 loop + if i < n then + mask(i) := '1'; + end if; + end loop; + carry := or (rs and mask) and rs(31); + return carry & std_ulogic_vector(resize(tmp, rs'length)); + end; + + function ppc_sld (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable n : integer; + begin + n := to_integer(unsigned(rb(6 downto 0))); + return std_ulogic_vector(shift_left(unsigned(rs), n)); + end; + + function ppc_srd (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable n : integer; + begin + n := to_integer(unsigned(rb(6 downto 0))); + return std_ulogic_vector(shift_right(unsigned(rs), n)); + end; + + function ppc_sradi (rs: std_ulogic_vector(63 downto 0); sh: std_ulogic_vector(5 downto 0)) return std_ulogic_vector is + variable n : integer; + variable carry: std_ulogic; + variable mask : std_ulogic_vector(63 downto 0); + begin + n := to_integer(unsigned(sh)); + -- what about n = 0? + mask := (others => '0'); + for i in 0 to 63 loop + if i < n then + mask(i) := '1'; + end if; + end loop; + carry := '0' when (rs and mask) = (63 downto 0 => '0') else rs(63); + + return carry & std_ulogic_vector(shift_right(signed(rs), n)); + end; + + function ppc_srad (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable n : integer; + variable carry: std_ulogic; + variable mask : std_ulogic_vector(63 downto 0); + begin + n := to_integer(unsigned(rb(6 downto 0))); + -- what about n = 0? + mask := (others => '0'); + for i in 0 to 63 loop + if i < n then + mask(i) := '1'; + end if; + end loop; + carry := '0' when (rs and mask) = (63 downto 0 => '0') else rs(63); + + return carry & std_ulogic_vector(shift_right(signed(rs), n)); + end; + + -- Not sure how to better communicate the top 64 bits of the result is unused + function ppc_mulld (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable tmp: signed(127 downto 0); + begin + tmp := signed(ra) * signed(rb); + return std_ulogic_vector(tmp(63 downto 0)); + end; + + -- Not sure how to better communicate the top 64 bits of the result is unused + function ppc_mulhd (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable tmp: signed(127 downto 0); + begin + tmp := signed(ra) * signed(rb); + return std_ulogic_vector(tmp(127 downto 64)); + end; + + -- Not sure how to better communicate the top 64 bits of the result is unused + function ppc_mulhdu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable tmp: unsigned(127 downto 0); + begin + tmp := unsigned(ra) * unsigned(rb); + return std_ulogic_vector(tmp(127 downto 64)); + end; + + -- Not sure how to better communicate the top 16 bits of the result is unused + function ppc_mulli (ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0)) return std_ulogic_vector is + variable tmp: signed(79 downto 0); + begin + tmp := signed(ra) * signed(si); + return std_ulogic_vector(tmp(63 downto 0)); + end; + + function ppc_mullw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + begin + return std_ulogic_vector(signed(ra(31 downto 0)) * signed(rb(31 downto 0))); + end; + + function ppc_mulhw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable tmp: signed(63 downto 0); + begin + tmp := signed(ra(31 downto 0)) * signed(rb(31 downto 0)); + return std_ulogic_vector(tmp(63 downto 32)) & std_ulogic_vector(tmp(63 downto 32)); + end; + + function ppc_mulhwu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable tmp: unsigned(63 downto 0); + begin + tmp := unsigned(ra(31 downto 0)) * unsigned(rb(31 downto 0)); + return std_ulogic_vector(tmp(63 downto 32)) & std_ulogic_vector(tmp(63 downto 32)); + end; + + function ppc_cmpi (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0); so: std_ulogic) return std_ulogic_vector is - variable tmp: signed(ra'range); - begin - tmp := signed(ra); - if l = '0' then - tmp := resize(signed(ra(31 downto 0)), tmp'length); - end if; + variable tmp: signed(ra'range); + begin + tmp := signed(ra); + if l = '0' then + tmp := resize(signed(ra(31 downto 0)), tmp'length); + end if; - return ppc_signed_compare(tmp, resize(signed(si), tmp'length), so); - end; + return ppc_signed_compare(tmp, resize(signed(si), tmp'length), so); + end; - function ppc_cmp (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0); + function ppc_cmp (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0); so: std_ulogic) return std_ulogic_vector is - variable tmpa, tmpb: signed(ra'range); - begin - tmpa := signed(ra); - tmpb := signed(rb); - if l = '0' then - tmpa := resize(signed(ra(31 downto 0)), ra'length); - tmpb := resize(signed(rb(31 downto 0)), ra'length); - end if; - - return ppc_signed_compare(tmpa, tmpb, so); - end; - - function ppc_cmpli (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0); + variable tmpa, tmpb: signed(ra'range); + begin + tmpa := signed(ra); + tmpb := signed(rb); + if l = '0' then + tmpa := resize(signed(ra(31 downto 0)), ra'length); + tmpb := resize(signed(rb(31 downto 0)), ra'length); + end if; + + return ppc_signed_compare(tmpa, tmpb, so); + end; + + function ppc_cmpli (l: std_ulogic; ra: std_ulogic_vector(63 downto 0); si: std_ulogic_vector(15 downto 0); so: std_ulogic) return std_ulogic_vector is - variable tmp: unsigned(ra'range); - begin - tmp := unsigned(ra); - if l = '0' then - tmp := resize(unsigned(ra(31 downto 0)), tmp'length); - end if; + variable tmp: unsigned(ra'range); + begin + tmp := unsigned(ra); + if l = '0' then + tmp := resize(unsigned(ra(31 downto 0)), tmp'length); + end if; - return ppc_unsigned_compare(tmp, resize(unsigned(si), tmp'length), so); - end; + return ppc_unsigned_compare(tmp, resize(unsigned(si), tmp'length), so); + end; - function ppc_cmpl (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0); + function ppc_cmpl (l: std_ulogic; ra, rb: std_ulogic_vector(63 downto 0); so: std_ulogic) return std_ulogic_vector is - variable tmpa, tmpb: unsigned(ra'range); - begin - tmpa := unsigned(ra); - tmpb := unsigned(rb); - if l = '0' then - tmpa := resize(unsigned(ra(31 downto 0)), ra'length); - tmpb := resize(unsigned(rb(31 downto 0)), ra'length); - end if; - - return ppc_unsigned_compare(tmpa, tmpb, so); - end; - - function ppc_cmpb (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable ret: std_ulogic_vector (rs'range); - variable hi: integer; - variable lo: integer; - begin - for i in 1 to 8 loop - hi := (8*i)-1; - lo := 8*(i-1); - ret(hi downto lo) := cmp_one_byte(rs(hi downto lo), rb(hi downto lo)); - end loop; - - return ret; - end; + variable tmpa, tmpb: unsigned(ra'range); + begin + tmpa := unsigned(ra); + tmpb := unsigned(rb); + if l = '0' then + tmpa := resize(unsigned(ra(31 downto 0)), ra'length); + tmpb := resize(unsigned(rb(31 downto 0)), ra'length); + end if; + + return ppc_unsigned_compare(tmpa, tmpb, so); + end; + + function ppc_cmpb (rs, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable ret: std_ulogic_vector (rs'range); + variable hi: integer; + variable lo: integer; + begin + for i in 1 to 8 loop + hi := (8*i)-1; + lo := 8*(i-1); + ret(hi downto lo) := cmp_one_byte(rs(hi downto lo), rb(hi downto lo)); + end loop; + + return ret; + end; function ppc_cmpeqb (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is variable match: std_ulogic; @@ -776,60 +776,60 @@ package body ppc_fx_insns is return '0' & match & "00"; end; - -- Not synthesizable - function ppc_divw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable tmp: signed(31 downto 0); - begin - tmp := signed(ra(31 downto 0)) / signed(rb(31 downto 0)); - - return (63 downto 32 => '0') & std_ulogic_vector(tmp); - end; - - function ppc_divdu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable tmp: unsigned(63 downto 0) := (others => '0'); - begin - if unsigned(rb) /= 0 then - tmp := unsigned(ra) / unsigned(rb); - end if; - - return std_ulogic_vector(tmp); - end; - - function ppc_divd (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable tmp: signed(63 downto 0) := (others => '0'); - begin - if signed(rb) /= 0 then - tmp := signed(ra) / signed(rb); - end if; - - return std_ulogic_vector(tmp); - end; - - function ppc_divwu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is - variable tmp: unsigned(31 downto 0) := (others => '0'); - begin - if unsigned(rb(31 downto 0)) /= 0 then - tmp := unsigned(ra(31 downto 0)) / unsigned(rb(31 downto 0)); - end if; - - return std_ulogic_vector(resize(tmp, ra'length)); - end; - - function ppc_bc_taken(bo, bi: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0); ctr: std_ulogic_vector(63 downto 0)) return std_ulogic is - variable crfield: integer; - variable crbit_match: std_ulogic; - variable ctr_not_zero: std_ulogic; - variable ctr_ok: std_ulogic; - variable cond_ok: std_ulogic; - begin - crfield := to_integer(unsigned(bi)); - -- BE bit numbering - crbit_match := '1' when cr(31-crfield) = bo(4-1) else '0'; - -- We check this before it is decremented - ctr_not_zero := '1' when ctr /= x"0000000000000001" else '0'; - ctr_ok := bo(4-2) or (ctr_not_zero xor bo(4-3)); - cond_ok := bo(4-0) or crbit_match; + -- Not synthesizable + function ppc_divw (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable tmp: signed(31 downto 0); + begin + tmp := signed(ra(31 downto 0)) / signed(rb(31 downto 0)); + + return (63 downto 32 => '0') & std_ulogic_vector(tmp); + end; + + function ppc_divdu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable tmp: unsigned(63 downto 0) := (others => '0'); + begin + if unsigned(rb) /= 0 then + tmp := unsigned(ra) / unsigned(rb); + end if; + + return std_ulogic_vector(tmp); + end; + + function ppc_divd (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable tmp: signed(63 downto 0) := (others => '0'); + begin + if signed(rb) /= 0 then + tmp := signed(ra) / signed(rb); + end if; + + return std_ulogic_vector(tmp); + end; + + function ppc_divwu (ra, rb: std_ulogic_vector(63 downto 0)) return std_ulogic_vector is + variable tmp: unsigned(31 downto 0) := (others => '0'); + begin + if unsigned(rb(31 downto 0)) /= 0 then + tmp := unsigned(ra(31 downto 0)) / unsigned(rb(31 downto 0)); + end if; + + return std_ulogic_vector(resize(tmp, ra'length)); + end; + + function ppc_bc_taken(bo, bi: std_ulogic_vector(4 downto 0); cr: std_ulogic_vector(31 downto 0); ctr: std_ulogic_vector(63 downto 0)) return std_ulogic is + variable crfield: integer; + variable crbit_match: std_ulogic; + variable ctr_not_zero: std_ulogic; + variable ctr_ok: std_ulogic; + variable cond_ok: std_ulogic; + begin + crfield := to_integer(unsigned(bi)); + -- BE bit numbering + crbit_match := '1' when cr(31-crfield) = bo(4-1) else '0'; + -- We check this before it is decremented + ctr_not_zero := '1' when ctr /= x"0000000000000001" else '0'; + ctr_ok := bo(4-2) or (ctr_not_zero xor bo(4-3)); + cond_ok := bo(4-0) or crbit_match; return ctr_ok and cond_ok; - end; + end; end package body ppc_fx_insns; diff --git a/sim_bram.vhdl b/sim_bram.vhdl index d2d4f1b..54abeb4 100644 --- a/sim_bram.vhdl +++ b/sim_bram.vhdl @@ -13,55 +13,55 @@ use work.sim_bram_helpers.all; entity main_bram is generic( - WIDTH : natural := 64; - HEIGHT_BITS : natural := 1024; - MEMORY_SIZE : natural := 65536; - RAM_INIT_FILE : string - ); + WIDTH : natural := 64; + HEIGHT_BITS : natural := 1024; + MEMORY_SIZE : natural := 65536; + RAM_INIT_FILE : string + ); port( - clk : in std_logic; - addr : in std_logic_vector(HEIGHT_BITS - 1 downto 0) ; - di : in std_logic_vector(WIDTH-1 downto 0); - do : out std_logic_vector(WIDTH-1 downto 0); - sel : in std_logic_vector((WIDTH/8)-1 downto 0); - re : in std_ulogic; - we : in std_ulogic - ); + clk : in std_logic; + addr : in std_logic_vector(HEIGHT_BITS - 1 downto 0) ; + di : in std_logic_vector(WIDTH-1 downto 0); + do : out std_logic_vector(WIDTH-1 downto 0); + sel : in std_logic_vector((WIDTH/8)-1 downto 0); + re : in std_ulogic; + we : in std_ulogic + ); end entity main_bram; architecture sim of main_bram is constant WIDTH_BYTES : natural := WIDTH / 8; constant pad_zeros : std_ulogic_vector(log2(WIDTH_BYTES)-1 downto 0) - := (others => '0'); + := (others => '0'); signal identifier : integer := behavioural_initialize(filename => RAM_INIT_FILE, - size => MEMORY_SIZE); + size => MEMORY_SIZE); -- Others signal obuf : std_logic_vector(WIDTH-1 downto 0); begin -- Actual RAM template memory_0: process(clk) - variable ret_dat_v : std_ulogic_vector(63 downto 0); - variable addr64 : std_ulogic_vector(63 downto 0); + variable ret_dat_v : std_ulogic_vector(63 downto 0); + variable addr64 : std_ulogic_vector(63 downto 0); begin - if rising_edge(clk) then - addr64 := (others => '0'); - addr64(HEIGHT_BITS + 2 downto 3) := addr; - if we = '1' then - report "RAM writing " & to_hstring(di) & " to " & - to_hstring(addr & pad_zeros) & " sel:" & to_hstring(sel); - behavioural_write(di, addr64, to_integer(unsigned(sel)), identifier); - end if; - if re = '1' then - behavioural_read(ret_dat_v, addr64, to_integer(unsigned(sel)), identifier); - report "RAM reading from " & to_hstring(addr & pad_zeros) & - " returns " & to_hstring(ret_dat_v); - obuf <= ret_dat_v(obuf'left downto 0); - end if; - do <= obuf; - end if; + if rising_edge(clk) then + addr64 := (others => '0'); + addr64(HEIGHT_BITS + 2 downto 3) := addr; + if we = '1' then + report "RAM writing " & to_hstring(di) & " to " & + to_hstring(addr & pad_zeros) & " sel:" & to_hstring(sel); + behavioural_write(di, addr64, to_integer(unsigned(sel)), identifier); + end if; + if re = '1' then + behavioural_read(ret_dat_v, addr64, to_integer(unsigned(sel)), identifier); + report "RAM reading from " & to_hstring(addr & pad_zeros) & + " returns " & to_hstring(ret_dat_v); + obuf <= ret_dat_v(obuf'left downto 0); + end if; + do <= obuf; + end if; end process; end architecture sim; diff --git a/wishbone_debug_master.vhdl b/wishbone_debug_master.vhdl index ddf6923..e0d5923 100644 --- a/wishbone_debug_master.vhdl +++ b/wishbone_debug_master.vhdl @@ -6,30 +6,30 @@ library work; use work.wishbone_types.all; entity wishbone_debug_master is - port(clk : in std_ulogic; - rst : in std_ulogic; - - -- Debug bus interface - dmi_addr : in std_ulogic_vector(1 downto 0); - dmi_din : in std_ulogic_vector(63 downto 0); - dmi_dout : out std_ulogic_vector(63 downto 0); - dmi_req : in std_ulogic; - dmi_wr : in std_ulogic; - dmi_ack : out std_ulogic; - - -- Wishbone master interface - wb_out : out wishbone_master_out; - wb_in : in wishbone_slave_out - ); + port(clk : in std_ulogic; + rst : in std_ulogic; + + -- Debug bus interface + dmi_addr : in std_ulogic_vector(1 downto 0); + dmi_din : in std_ulogic_vector(63 downto 0); + dmi_dout : out std_ulogic_vector(63 downto 0); + dmi_req : in std_ulogic; + dmi_wr : in std_ulogic; + dmi_ack : out std_ulogic; + + -- Wishbone master interface + wb_out : out wishbone_master_out; + wb_in : in wishbone_slave_out + ); end entity wishbone_debug_master; architecture behaviour of wishbone_debug_master is -- ** Register offsets definitions. All registers are 64-bit - constant DBG_WB_ADDR : std_ulogic_vector(1 downto 0) := "00"; - constant DBG_WB_DATA : std_ulogic_vector(1 downto 0) := "01"; - constant DBG_WB_CTRL : std_ulogic_vector(1 downto 0) := "10"; - constant DBG_WB_RSVD : std_ulogic_vector(1 downto 0) := "11"; + constant DBG_WB_ADDR : std_ulogic_vector(1 downto 0) := "00"; + constant DBG_WB_DATA : std_ulogic_vector(1 downto 0) := "01"; + constant DBG_WB_CTRL : std_ulogic_vector(1 downto 0) := "10"; + constant DBG_WB_RSVD : std_ulogic_vector(1 downto 0) := "11"; -- CTRL register: -- @@ -42,10 +42,10 @@ architecture behaviour of wishbone_debug_master is -- 11 - +8 -- ** Address and control registers and read data - signal reg_addr : std_ulogic_vector(63 downto 0); - signal reg_ctrl_out : std_ulogic_vector(63 downto 0); - signal reg_ctrl : std_ulogic_vector(10 downto 0); - signal data_latch : std_ulogic_vector(63 downto 0); + signal reg_addr : std_ulogic_vector(63 downto 0); + signal reg_ctrl_out : std_ulogic_vector(63 downto 0); + signal reg_ctrl : std_ulogic_vector(10 downto 0); + signal data_latch : std_ulogic_vector(63 downto 0); type state_t is (IDLE, WB_CYCLE, DMI_WAIT); signal state : state_t; @@ -55,49 +55,49 @@ begin -- Hard wire unused bits to 0 reg_ctrl_out <= (63 downto 11 => '0', - 10 downto 0 => reg_ctrl); + 10 downto 0 => reg_ctrl); -- DMI read data mux with dmi_addr select dmi_dout <= - reg_addr when DBG_WB_ADDR, - data_latch when DBG_WB_DATA, - reg_ctrl_out when DBG_WB_CTRL, - (others => '0') when others; + reg_addr when DBG_WB_ADDR, + data_latch when DBG_WB_DATA, + reg_ctrl_out when DBG_WB_CTRL, + (others => '0') when others; -- ADDR and CTRL register writes reg_write : process(clk) - subtype autoinc_inc_t is integer range 1 to 8; - function decode_autoinc(c : std_ulogic_vector(1 downto 0)) - return autoinc_inc_t is - begin - case c is - when "00" => return 1; - when "01" => return 2; - when "10" => return 4; - when "11" => return 8; - -- Below shouldn't be necessary but GHDL complains - when others => return 8; - end case; - end function decode_autoinc; + subtype autoinc_inc_t is integer range 1 to 8; + function decode_autoinc(c : std_ulogic_vector(1 downto 0)) + return autoinc_inc_t is + begin + case c is + when "00" => return 1; + when "01" => return 2; + when "10" => return 4; + when "11" => return 8; + -- Below shouldn't be necessary but GHDL complains + when others => return 8; + end case; + end function decode_autoinc; begin - if rising_edge(clk) then - if (rst) then - reg_addr <= (others => '0'); - reg_ctrl <= (others => '0'); - else -- Standard register writes + if rising_edge(clk) then + if (rst) then + reg_addr <= (others => '0'); + reg_ctrl <= (others => '0'); + else -- Standard register writes if do_inc = '1' then - -- Address register auto-increment - reg_addr <= std_ulogic_vector(unsigned(reg_addr) + - decode_autoinc(reg_ctrl(10 downto 9))); + -- Address register auto-increment + reg_addr <= std_ulogic_vector(unsigned(reg_addr) + + decode_autoinc(reg_ctrl(10 downto 9))); elsif dmi_req and dmi_wr then - if dmi_addr = DBG_WB_ADDR then - reg_addr <= dmi_din; - elsif dmi_addr = DBG_WB_CTRL then - reg_ctrl <= dmi_din(10 downto 0); - end if; - end if; - end if; - end if; + if dmi_addr = DBG_WB_ADDR then + reg_addr <= dmi_din; + elsif dmi_addr = DBG_WB_CTRL then + reg_ctrl <= dmi_din(10 downto 0); + end if; + end if; + end if; + end if; end process; -- ACK is hard wired to req for register writes. For data read/writes @@ -117,7 +117,7 @@ begin -- dmi_ack <= dmi_req when (dmi_addr /= DBG_WB_DATA or state = DMI_WAIT) else '0'; - -- Some WB signals are direct wires from registers or DMI + -- Some WB signals are direct wires from registers or DMI wb_out.adr <= reg_addr(wb_out.adr'left downto 0); wb_out.dat <= dmi_din; wb_out.sel <= reg_ctrl(7 downto 0); @@ -132,47 +132,47 @@ begin -- latch_reads : process(clk) begin - if rising_edge(clk) then - if state = WB_CYCLE and wb_in.ack = '1' and dmi_wr = '0' then - data_latch <= wb_in.dat; - end if; - end if; + if rising_edge(clk) then + if state = WB_CYCLE and wb_in.ack = '1' and dmi_wr = '0' then + data_latch <= wb_in.dat; + end if; + end if; end process; -- Command state machine (generate wb_cyc) wb_trigger : process(clk) begin - if rising_edge(clk) then - if (rst) then - state <= IDLE; - wb_out.stb <= '0'; + if rising_edge(clk) then + if (rst) then + state <= IDLE; + wb_out.stb <= '0'; do_inc <= '0'; - else - case state is - when IDLE => - if dmi_req = '1' and dmi_addr = DBG_WB_DATA then - state <= WB_CYCLE; - wb_out.stb <= '1'; - end if; - when WB_CYCLE => - if wb_in.stall = '0' then - wb_out.stb <= '0'; - end if; - if wb_in.ack then - -- We shouldn't get the ack if we hadn't already cleared - -- stb above but if this happen, don't leave it dangling. - -- - wb_out.stb <= '0'; - state <= DMI_WAIT; + else + case state is + when IDLE => + if dmi_req = '1' and dmi_addr = DBG_WB_DATA then + state <= WB_CYCLE; + wb_out.stb <= '1'; + end if; + when WB_CYCLE => + if wb_in.stall = '0' then + wb_out.stb <= '0'; + end if; + if wb_in.ack then + -- We shouldn't get the ack if we hadn't already cleared + -- stb above but if this happen, don't leave it dangling. + -- + wb_out.stb <= '0'; + state <= DMI_WAIT; do_inc <= reg_ctrl(8); - end if; - when DMI_WAIT => - if dmi_req = '0' then - state <= IDLE; - end if; + end if; + when DMI_WAIT => + if dmi_req = '0' then + state <= IDLE; + end if; do_inc <= '0'; - end case; - end if; - end if; + end case; + end if; + end if; end process; end architecture behaviour; diff --git a/xics.vhdl b/xics.vhdl index b644051..45758f8 100644 --- a/xics.vhdl +++ b/xics.vhdl @@ -32,25 +32,25 @@ entity xics_icp is wb_in : in wb_io_master_out; wb_out : out wb_io_slave_out; - ics_in : in ics_to_icp_t; - core_irq_out : out std_ulogic + ics_in : in ics_to_icp_t; + core_irq_out : out std_ulogic ); end xics_icp; architecture behaviour of xics_icp is type reg_internal_t is record - xisr : std_ulogic_vector(23 downto 0); - cppr : std_ulogic_vector(7 downto 0); - mfrr : std_ulogic_vector(7 downto 0); - irq : std_ulogic; - wb_rd_data : std_ulogic_vector(31 downto 0); - wb_ack : std_ulogic; + xisr : std_ulogic_vector(23 downto 0); + cppr : std_ulogic_vector(7 downto 0); + mfrr : std_ulogic_vector(7 downto 0); + irq : std_ulogic; + wb_rd_data : std_ulogic_vector(31 downto 0); + wb_ack : std_ulogic; end record; constant reg_internal_init : reg_internal_t := - (wb_ack => '0', - mfrr => x"ff", -- mask everything on reset - irq => '0', - others => (others => '0')); + (wb_ack => '0', + mfrr => x"ff", -- mask everything on reset + irq => '0', + others => (others => '0')); signal r, r_next : reg_internal_t; @@ -67,12 +67,12 @@ begin regs : process(clk) begin - if rising_edge(clk) then - r <= r_next; + if rising_edge(clk) then + r <= r_next; -- We delay core_irq_out by a cycle to help with timing core_irq_out <= r.irq; - end if; + end if; end process; wb_out.dat <= r.wb_rd_data; @@ -80,8 +80,8 @@ begin wb_out.stall <= '0'; -- never stall wishbone comb : process(all) - variable v : reg_internal_t; - variable xirr_accept_rd : std_ulogic; + variable v : reg_internal_t; + variable xirr_accept_rd : std_ulogic; function bswap(v : in std_ulogic_vector(31 downto 0)) return std_ulogic_vector is variable r : std_ulogic_vector(31 downto 0); @@ -96,65 +96,65 @@ begin variable be_in : std_ulogic_vector(31 downto 0); variable be_out : std_ulogic_vector(31 downto 0); - variable pending_priority : std_ulogic_vector(7 downto 0); + variable pending_priority : std_ulogic_vector(7 downto 0); begin - v := r; + v := r; - v.wb_ack := '0'; + v.wb_ack := '0'; - xirr_accept_rd := '0'; + xirr_accept_rd := '0'; be_in := bswap(wb_in.dat); be_out := (others => '0'); - if wb_in.cyc = '1' and wb_in.stb = '1' then - v.wb_ack := '1'; -- always ack - if wb_in.we = '1' then -- write - -- writes to both XIRR are the same - case wb_in.adr(7 downto 0) is + if wb_in.cyc = '1' and wb_in.stb = '1' then + v.wb_ack := '1'; -- always ack + if wb_in.we = '1' then -- write + -- writes to both XIRR are the same + case wb_in.adr(7 downto 0) is when XIRR_POLL => - report "ICP XIRR_POLL write"; + report "ICP XIRR_POLL write"; v.cppr := be_in(31 downto 24); when XIRR => v.cppr := be_in(31 downto 24); - if wb_in.sel = x"f" then -- 4 byte + if wb_in.sel = x"f" then -- 4 byte report "ICP XIRR write word (EOI) :" & to_hstring(be_in); - elsif wb_in.sel = x"1" then -- 1 byte + elsif wb_in.sel = x"1" then -- 1 byte report "ICP XIRR write byte (CPPR):" & to_hstring(be_in(31 downto 24)); else report "ICP XIRR UNSUPPORTED write ! sel=" & to_hstring(wb_in.sel); - end if; - when MFRR => + end if; + when MFRR => v.mfrr := be_in(31 downto 24); - if wb_in.sel = x"f" then -- 4 bytes + if wb_in.sel = x"f" then -- 4 bytes report "ICP MFRR write word:" & to_hstring(be_in); - elsif wb_in.sel = x"1" then -- 1 byte + elsif wb_in.sel = x"1" then -- 1 byte report "ICP MFRR write byte:" & to_hstring(be_in(31 downto 24)); else report "ICP MFRR UNSUPPORTED write ! sel=" & to_hstring(wb_in.sel); - end if; + end if; when others => - end case; + end case; - else -- read + else -- read - case wb_in.adr(7 downto 0) is + case wb_in.adr(7 downto 0) is when XIRR_POLL => report "ICP XIRR_POLL read"; be_out := r.cppr & r.xisr; when XIRR => report "ICP XIRR read"; be_out := r.cppr & r.xisr; - if wb_in.sel = x"f" then - xirr_accept_rd := '1'; - end if; - when MFRR => + if wb_in.sel = x"f" then + xirr_accept_rd := '1'; + end if; + when MFRR => report "ICP MFRR read"; be_out(31 downto 24) := r.mfrr; when others => - end case; - end if; - end if; + end case; + end if; + end if; pending_priority := x"ff"; v.xisr := x"000000"; @@ -171,14 +171,14 @@ begin pending_priority := r.mfrr; end if; - -- Accept the interrupt - if xirr_accept_rd = '1' then + -- Accept the interrupt + if xirr_accept_rd = '1' then report "XICS: ICP ACCEPT" & " cppr:" & to_hstring(r.cppr) & " xisr:" & to_hstring(r.xisr) & " mfrr:" & to_hstring(r.mfrr); - v.cppr := pending_priority; - end if; + v.cppr := pending_priority; + end if; v.wb_rd_data := bswap(be_out); @@ -191,11 +191,11 @@ begin report "IRQ clr"; end if; - if rst = '1' then - v := reg_internal_init; - end if; + if rst = '1' then + v := reg_internal_init; + end if; - r_next <= v; + r_next <= v; end process; @@ -221,8 +221,8 @@ entity xics_ics is wb_in : in wb_io_master_out; wb_out : out wb_io_slave_out; - int_level_in : in std_ulogic_vector(SRC_NUM - 1 downto 0); - icp_out : out ics_to_icp_t + int_level_in : in std_ulogic_vector(SRC_NUM - 1 downto 0); + icp_out : out ics_to_icp_t ); end xics_ics;