Merge pull request #308 from antonblanchard/small-fixes

Fix some whitespace issues
remove-potato-uart
Michael Neuling 3 years ago committed by GitHub
commit b885ee7ed1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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

@ -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;


@ -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;

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;

-- 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;

@ -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…
Cancel
Save