mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-11 23:43:15 +00:00
Fix some whitespace issues
Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
This commit is contained in:
parent
46cde3bb23
commit
7994b98404
180
core_debug.vhdl
180
core_debug.vhdl
@ -12,25 +12,25 @@ entity core_debug is
|
||||
LOG_LENGTH : natural := 512
|
||||
);
|
||||
port (
|
||||
clk : in std_logic;
|
||||
rst : in std_logic;
|
||||
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;
|
||||
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;
|
||||
-- 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);
|
||||
-- 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));
|
||||
-- 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;
|
||||
-- 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
|
||||
|
||||
@ -66,59 +66,59 @@ use unisim.vcomponents.all;
|
||||
|
||||
entity dmi_dtm is
|
||||
generic(ABITS : INTEGER:=8;
|
||||
DBITS : INTEGER:=32);
|
||||
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
|
||||
);
|
||||
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
|
||||
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;
|
||||
-- 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;
|
||||
-- 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;
|
||||
-- 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;
|
||||
-- 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 if;
|
||||
end if;
|
||||
end process;
|
||||
end architecture behaviour;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
1504
ppc_fx_insns.vhdl
1504
ppc_fx_insns.vhdl
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
|
||||
@ -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;
|
||||
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;
|
||||
-- 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
|
||||
);
|
||||
-- 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;
|
||||
|
||||
108
xics.vhdl
108
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;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user