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 LOG_LENGTH : natural := 512
); );
port ( port (
clk : in std_logic; clk : in std_logic;
rst : in std_logic; rst : in std_logic;


dmi_addr : in std_ulogic_vector(3 downto 0); dmi_addr : in std_ulogic_vector(3 downto 0);
dmi_din : in std_ulogic_vector(63 downto 0); dmi_din : in std_ulogic_vector(63 downto 0);
dmi_dout : out std_ulogic_vector(63 downto 0); dmi_dout : out std_ulogic_vector(63 downto 0);
dmi_req : in std_ulogic; dmi_req : in std_ulogic;
dmi_wr : in std_ulogic; dmi_wr : in std_ulogic;
dmi_ack : out std_ulogic; dmi_ack : out std_ulogic;


-- Debug actions -- Debug actions
core_stop : out std_ulogic; core_stop : out std_ulogic;
core_rst : out std_ulogic; core_rst : out std_ulogic;
icache_rst : out std_ulogic; icache_rst : out std_ulogic;


-- Core status inputs -- Core status inputs
terminate : in std_ulogic; terminate : in std_ulogic;
core_stopped : in std_ulogic; core_stopped : in std_ulogic;
nia : in std_ulogic_vector(63 downto 0); nia : in std_ulogic_vector(63 downto 0);
msr : in std_ulogic_vector(63 downto 0); msr : in std_ulogic_vector(63 downto 0);


-- GSPR register read port -- GSPR register read port
@ -45,8 +45,8 @@ entity core_debug is
log_read_data : out std_ulogic_vector(63 downto 0); log_read_data : out std_ulogic_vector(63 downto 0);
log_write_addr : out std_ulogic_vector(31 downto 0); log_write_addr : out std_ulogic_vector(31 downto 0);


-- Misc -- Misc
terminated_out : out std_ulogic terminated_out : out std_ulogic
); );
end core_debug; end core_debug;


@ -60,7 +60,7 @@ architecture behave of core_debug is
-- bit 2 : Icache reset -- bit 2 : Icache reset
-- bit 3 : Single step -- bit 3 : Single step
-- bit 4 : Core start -- 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_STOP : integer := 0;
constant DBG_CORE_CTRL_RESET : integer := 1; constant DBG_CORE_CTRL_RESET : integer := 1;
constant DBG_CORE_CTRL_ICRESET : integer := 2; 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 0 : Core stopping (wait til bit 1 set)
-- bit 1 : Core stopped -- bit 1 : Core stopped
-- bit 2 : Core terminated (clears with start or reset) -- 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_STOPPING : integer := 0;
constant DBG_CORE_STAT_STOPPED : integer := 1; constant DBG_CORE_STAT_STOPPED : integer := 1;
constant DBG_CORE_STAT_TERM : integer := 2; constant DBG_CORE_STAT_TERM : integer := 2;


-- NIA register (read only for now) -- 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) -- MSR (read only)
constant DBG_CORE_MSR : std_ulogic_vector(3 downto 0) := "0011"; 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 do_gspr_rd : std_ulogic;
signal gspr_index : gspr_index_t; signal gspr_index : gspr_index_t;


signal log_dmi_addr : std_ulogic_vector(31 downto 0) := (others => '0'); 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_data : std_ulogic_vector(63 downto 0) := (others => '0');
signal log_dmi_trigger : 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_log_trigger : std_ulogic := '0';
signal do_dmi_log_rd : std_ulogic; signal do_dmi_log_rd : std_ulogic;
signal dmi_read_log_data : std_ulogic; signal dmi_read_log_data : std_ulogic;
signal dmi_read_log_data_1 : 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 begin
-- Single cycle register accesses on DMI except for GSPR data -- Single cycle register accesses on DMI except for GSPR data
@ -125,36 +125,36 @@ begin


-- Status register read composition -- Status register read composition
stat_reg <= (2 => terminated, stat_reg <= (2 => terminated,
1 => core_stopped, 1 => core_stopped,
0 => stopping, 0 => stopping,
others => '0'); others => '0');


-- DMI read data mux -- DMI read data mux
with dmi_addr select dmi_dout <= with dmi_addr select dmi_dout <=
stat_reg when DBG_CORE_STAT, stat_reg when DBG_CORE_STAT,
nia when DBG_CORE_NIA, nia when DBG_CORE_NIA,
msr when DBG_CORE_MSR, msr when DBG_CORE_MSR,
dbg_gpr_data when DBG_CORE_GSPR_DATA, dbg_gpr_data when DBG_CORE_GSPR_DATA,
log_write_addr & log_dmi_addr when DBG_CORE_LOG_ADDR, log_write_addr & log_dmi_addr when DBG_CORE_LOG_ADDR,
log_dmi_data when DBG_CORE_LOG_DATA, log_dmi_data when DBG_CORE_LOG_DATA,
log_dmi_trigger when DBG_CORE_LOG_TRIGGER, log_dmi_trigger when DBG_CORE_LOG_TRIGGER,
(others => '0') when others; (others => '0') when others;


-- DMI writes -- DMI writes
reg_write: process(clk) reg_write: process(clk)
begin begin
if rising_edge(clk) then if rising_edge(clk) then
-- Reset the 1-cycle "do" signals -- Reset the 1-cycle "do" signals
do_step <= '0'; do_step <= '0';
do_reset <= '0'; do_reset <= '0';
do_icreset <= '0'; do_icreset <= '0';
do_dmi_log_rd <= '0'; do_dmi_log_rd <= '0';


if (rst) then if (rst) then
stopping <= '0'; stopping <= '0';
terminated <= '0'; terminated <= '0';
log_trigger_delay <= 0; log_trigger_delay <= 0;
else else
if do_log_trigger = '1' or log_trigger_delay /= 0 then if do_log_trigger = '1' or log_trigger_delay /= 0 then
if log_trigger_delay = 255 then if log_trigger_delay = 255 then
log_dmi_trigger(1) <= '1'; log_dmi_trigger(1) <= '1';
@ -163,32 +163,32 @@ begin
log_trigger_delay <= log_trigger_delay + 1; log_trigger_delay <= log_trigger_delay + 1;
end if; end if;
end if; end if;
-- Edge detect on dmi_req for 1-shot pulses -- Edge detect on dmi_req for 1-shot pulses
dmi_req_1 <= dmi_req; dmi_req_1 <= dmi_req;
if dmi_req = '1' and dmi_req_1 = '0' then if dmi_req = '1' and dmi_req_1 = '0' then
if dmi_wr = '1' then if dmi_wr = '1' then
report("DMI write to " & to_hstring(dmi_addr)); report("DMI write to " & to_hstring(dmi_addr));


-- Control register actions -- Control register actions
if dmi_addr = DBG_CORE_CTRL then if dmi_addr = DBG_CORE_CTRL then
if dmi_din(DBG_CORE_CTRL_RESET) = '1' then if dmi_din(DBG_CORE_CTRL_RESET) = '1' then
do_reset <= '1'; do_reset <= '1';
terminated <= '0'; terminated <= '0';
end if; end if;
if dmi_din(DBG_CORE_CTRL_STOP) = '1' then if dmi_din(DBG_CORE_CTRL_STOP) = '1' then
stopping <= '1'; stopping <= '1';
end if; end if;
if dmi_din(DBG_CORE_CTRL_STEP) = '1' then if dmi_din(DBG_CORE_CTRL_STEP) = '1' then
do_step <= '1'; do_step <= '1';
terminated <= '0'; terminated <= '0';
end if; end if;
if dmi_din(DBG_CORE_CTRL_ICRESET) = '1' then if dmi_din(DBG_CORE_CTRL_ICRESET) = '1' then
do_icreset <= '1'; do_icreset <= '1';
end if; end if;
if dmi_din(DBG_CORE_CTRL_START) = '1' then if dmi_din(DBG_CORE_CTRL_START) = '1' then
stopping <= '0'; stopping <= '0';
terminated <= '0'; terminated <= '0';
end if; end if;
elsif dmi_addr = DBG_CORE_GSPR_INDEX then elsif dmi_addr = DBG_CORE_GSPR_INDEX then
gspr_index <= dmi_din(gspr_index_t'left downto 0); gspr_index <= dmi_din(gspr_index_t'left downto 0);
elsif dmi_addr = DBG_CORE_LOG_ADDR then elsif dmi_addr = DBG_CORE_LOG_ADDR then
@ -196,17 +196,17 @@ begin
do_dmi_log_rd <= '1'; do_dmi_log_rd <= '1';
elsif dmi_addr = DBG_CORE_LOG_TRIGGER then elsif dmi_addr = DBG_CORE_LOG_TRIGGER then
log_dmi_trigger <= dmi_din; log_dmi_trigger <= dmi_din;
end if; end if;
else else
report("DMI read from " & to_string(dmi_addr)); report("DMI read from " & to_string(dmi_addr));
end if; end if;


elsif dmi_read_log_data = '0' and dmi_read_log_data_1 = '1' then 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 -- Increment log_dmi_addr after the end of a read from DBG_CORE_LOG_DATA
log_dmi_addr(LOG_INDEX_BITS + 1 downto 0) <= log_dmi_addr(LOG_INDEX_BITS + 1 downto 0) <=
std_ulogic_vector(unsigned(log_dmi_addr(LOG_INDEX_BITS+1 downto 0)) + 1); std_ulogic_vector(unsigned(log_dmi_addr(LOG_INDEX_BITS+1 downto 0)) + 1);
do_dmi_log_rd <= '1'; do_dmi_log_rd <= '1';
end if; end if;
dmi_read_log_data_1 <= dmi_read_log_data; dmi_read_log_data_1 <= dmi_read_log_data;
if dmi_req = '1' and dmi_addr = DBG_CORE_LOG_DATA then if dmi_req = '1' and dmi_addr = DBG_CORE_LOG_DATA then
dmi_read_log_data <= '1'; dmi_read_log_data <= '1';
@ -214,15 +214,15 @@ begin
dmi_read_log_data <= '0'; dmi_read_log_data <= '0';
end if; end if;


-- Set core stop on terminate. We'll be stopping some time *after* -- Set core stop on terminate. We'll be stopping some time *after*
-- the offending instruction, at least until we can do back flushes -- the offending instruction, at least until we can do back flushes
-- that preserve NIA which we can't just yet. -- that preserve NIA which we can't just yet.
if terminate = '1' then if terminate = '1' then
stopping <= '1'; stopping <= '1';
terminated <= '1'; terminated <= '1';
end if; end if;
end if; end if;
end if; end if;
end process; end process;


dbg_gpr_addr <= gspr_index; dbg_gpr_addr <= gspr_index;
@ -237,15 +237,15 @@ begin
maybe_log: if LOG_LENGTH > 0 generate maybe_log: if LOG_LENGTH > 0 generate
subtype log_ptr_t is unsigned(LOG_INDEX_BITS - 1 downto 0); 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); 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_array : log_array_t;
signal log_rd_ptr : log_ptr_t; signal log_rd_ptr : log_ptr_t;
signal log_wr_ptr : log_ptr_t; signal log_wr_ptr : log_ptr_t;
signal log_toggle : std_ulogic; signal log_toggle : std_ulogic;
signal log_wr_enable : std_ulogic; signal log_wr_enable : std_ulogic;
signal log_rd_ptr_latched : log_ptr_t; signal log_rd_ptr_latched : log_ptr_t;
signal log_rd : std_ulogic_vector(255 downto 0); signal log_rd : std_ulogic_vector(255 downto 0);
signal log_dmi_reading : std_ulogic; signal log_dmi_reading : std_ulogic;
signal log_dmi_read_done : std_ulogic; signal log_dmi_read_done : std_ulogic;


function select_dword(data : std_ulogic_vector(255 downto 0); function select_dword(data : std_ulogic_vector(255 downto 0);
addr : std_ulogic_vector(31 downto 0)) return std_ulogic_vector is addr : std_ulogic_vector(31 downto 0)) return std_ulogic_vector is

@ -66,59 +66,59 @@ use unisim.vcomponents.all;


entity dmi_dtm is entity dmi_dtm is
generic(ABITS : INTEGER:=8; generic(ABITS : INTEGER:=8;
DBITS : INTEGER:=32); DBITS : INTEGER:=32);


port(sys_clk : in std_ulogic; port(sys_clk : in std_ulogic;
sys_reset : in std_ulogic; sys_reset : in std_ulogic;
dmi_addr : out std_ulogic_vector(ABITS - 1 downto 0); dmi_addr : out std_ulogic_vector(ABITS - 1 downto 0);
dmi_din : in std_ulogic_vector(DBITS - 1 downto 0); dmi_din : in std_ulogic_vector(DBITS - 1 downto 0);
dmi_dout : out std_ulogic_vector(DBITS - 1 downto 0); dmi_dout : out std_ulogic_vector(DBITS - 1 downto 0);
dmi_req : out std_ulogic; dmi_req : out std_ulogic;
dmi_wr : out std_ulogic; dmi_wr : out std_ulogic;
dmi_ack : in std_ulogic dmi_ack : in std_ulogic
-- dmi_err : in std_ulogic TODO: Add error response -- dmi_err : in std_ulogic TODO: Add error response
); );
end entity dmi_dtm; end entity dmi_dtm;


architecture behaviour of dmi_dtm is architecture behaviour of dmi_dtm is


-- Signals coming out of the BSCANE2 block -- Signals coming out of the BSCANE2 block
signal jtag_reset : std_ulogic; signal jtag_reset : std_ulogic;
signal capture : std_ulogic; signal capture : std_ulogic;
signal update : std_ulogic; signal update : std_ulogic;
signal drck : std_ulogic; signal drck : std_ulogic;
signal jtag_clk : std_ulogic; signal jtag_clk : std_ulogic;
signal sel : std_ulogic; signal sel : std_ulogic;
signal shift : std_ulogic; signal shift : std_ulogic;
signal tdi : std_ulogic; signal tdi : std_ulogic;
signal tdo : std_ulogic; signal tdo : std_ulogic;
signal tck : std_ulogic; signal tck : std_ulogic;


-- ** JTAG clock domain ** -- ** JTAG clock domain **


-- Shift register -- Shift register
signal shiftr : std_ulogic_vector(ABITS + DBITS + 1 downto 0); signal shiftr : std_ulogic_vector(ABITS + DBITS + 1 downto 0);


-- Latched request -- 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 -- A request is present
signal jtag_req : std_ulogic; signal jtag_req : std_ulogic;


-- Synchronizer for jtag_rsp (sys clk -> jtag_clk) -- Synchronizer for jtag_rsp (sys clk -> jtag_clk)
signal dmi_ack_0 : std_ulogic; signal dmi_ack_0 : std_ulogic;
signal dmi_ack_1 : std_ulogic; signal dmi_ack_1 : std_ulogic;


-- ** sys clock domain ** -- ** sys clock domain **


-- Synchronizer for jtag_req (jtag clk -> sys clk) -- Synchronizer for jtag_req (jtag clk -> sys clk)
signal jtag_req_0 : std_ulogic; signal jtag_req_0 : std_ulogic;
signal jtag_req_1 : std_ulogic; signal jtag_req_1 : std_ulogic;


-- ** combination signals -- ** combination signals
signal jtag_bsy : std_ulogic; signal jtag_bsy : std_ulogic;
signal op_valid : std_ulogic; signal op_valid : std_ulogic;
signal rsp_op : std_ulogic_vector(1 downto 0); signal rsp_op : std_ulogic_vector(1 downto 0);


-- ** Constants ** -- ** Constants **
constant DMI_REQ_NOP : std_ulogic_vector(1 downto 0) := "00"; 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 -- Implement the Xilinx bscan2 for series 7 devices (TODO: use PoC to
-- wrap this if compatibility is required with older devices). -- wrap this if compatibility is required with older devices).
bscan : BSCANE2 bscan : BSCANE2
generic map ( generic map (
JTAG_CHAIN => 2 JTAG_CHAIN => 2
) )
port map ( port map (
CAPTURE => capture, CAPTURE => capture,
DRCK => drck, DRCK => drck,
RESET => jtag_reset, RESET => jtag_reset,
RUNTEST => open, RUNTEST => open,
SEL => sel, SEL => sel,
SHIFT => shift, SHIFT => shift,
TCK => tck, TCK => tck,
TDI => tdi, TDI => tdi,
TMS => open, TMS => open,
UPDATE => update, UPDATE => update,
TDO => tdo TDO => tdo
); );


-- Some examples out there suggest buffering the clock so it's -- Some examples out there suggest buffering the clock so it's
-- treated as a proper clock net. This is probably needed when using -- treated as a proper clock net. This is probably needed when using
@ -160,39 +160,39 @@ begin
-- missing the update phase so maybe not... -- missing the update phase so maybe not...
-- --
clkbuf : BUFG clkbuf : BUFG
port map ( port map (
-- I => drck, -- I => drck,
I => tck, I => tck,
O => jtag_clk O => jtag_clk
); );


-- dmi_req synchronization -- dmi_req synchronization
dmi_req_sync : process(sys_clk) dmi_req_sync : process(sys_clk)
begin begin
-- sys_reset is synchronous -- sys_reset is synchronous
if rising_edge(sys_clk) then if rising_edge(sys_clk) then
if (sys_reset = '1') then if (sys_reset = '1') then
jtag_req_0 <= '0'; jtag_req_0 <= '0';
jtag_req_1 <= '0'; jtag_req_1 <= '0';
else else
jtag_req_0 <= jtag_req; jtag_req_0 <= jtag_req;
jtag_req_1 <= jtag_req_0; jtag_req_1 <= jtag_req_0;
end if; end if;
end if; end if;
end process; end process;
dmi_req <= jtag_req_1; dmi_req <= jtag_req_1;


-- dmi_ack synchronization -- dmi_ack synchronization
dmi_ack_sync: process(jtag_clk, jtag_reset) dmi_ack_sync: process(jtag_clk, jtag_reset)
begin begin
-- jtag_reset is async (see comments) -- jtag_reset is async (see comments)
if jtag_reset = '1' then if jtag_reset = '1' then
dmi_ack_0 <= '0'; dmi_ack_0 <= '0';
dmi_ack_1 <= '0'; dmi_ack_1 <= '0';
elsif rising_edge(jtag_clk) then elsif rising_edge(jtag_clk) then
dmi_ack_0 <= dmi_ack; dmi_ack_0 <= dmi_ack;
dmi_ack_1 <= dmi_ack_0; dmi_ack_1 <= dmi_ack_0;
end if; end if;
end process; end process;
-- jtag_bsy indicates whether we can start a new request, we can when -- jtag_bsy indicates whether we can start a new request, we can when
@ -203,9 +203,9 @@ begin


-- decode request type in shift register -- decode request type in shift register
with shiftr(1 downto 0) select op_valid <= with shiftr(1 downto 0) select op_valid <=
'1' when DMI_REQ_RD, '1' when DMI_REQ_RD,
'1' when DMI_REQ_WR, '1' when DMI_REQ_WR,
'0' when others; '0' when others;


-- encode response op -- encode response op
rsp_op <= DMI_RSP_BSY when jtag_bsy = '1' else DMI_RSP_OK; 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) shifter: process(jtag_clk, jtag_reset, sys_reset)
begin begin
if jtag_reset = '1' or sys_reset = '1' then if jtag_reset = '1' or sys_reset = '1' then
shiftr <= (others => '0'); shiftr <= (others => '0');
jtag_req <= '0'; jtag_req <= '0';
request <= (others => '0'); request <= (others => '0');
elsif rising_edge(jtag_clk) then elsif rising_edge(jtag_clk) then


-- Handle jtag "commands" when sel is 1 -- Handle jtag "commands" when sel is 1
if sel = '1' then if sel = '1' then
-- Shift state, rotate the register -- Shift state, rotate the register
if shift = '1' then if shift = '1' then
shiftr <= tdi & shiftr(ABITS + DBITS + 1 downto 1); shiftr <= tdi & shiftr(ABITS + DBITS + 1 downto 1);
end if; end if;


-- Update state (trigger) -- Update state (trigger)
-- --
-- Latch the request if we aren't already processing one and -- Latch the request if we aren't already processing one and
-- it has a valid command opcode. -- it has a valid command opcode.
-- --
if update = '1' and op_valid = '1' then if update = '1' and op_valid = '1' then
if jtag_bsy = '0' then if jtag_bsy = '0' then
request <= shiftr; request <= shiftr;
jtag_req <= '1'; jtag_req <= '1';
end if; end if;
-- Set the shift register "op" to "busy". This will prevent -- Set the shift register "op" to "busy". This will prevent
-- us from re-starting the command on the next update if -- us from re-starting the command on the next update if
-- the command completes before that. -- the command completes before that.
shiftr(1 downto 0) <= DMI_RSP_BSY; shiftr(1 downto 0) <= DMI_RSP_BSY;
end if; end if;


-- Request completion. -- Request completion.
-- --
-- Capture the response data for reads and clear request flag. -- Capture the response data for reads and clear request flag.
-- --
-- Note: We clear req (and thus dmi_req) here which relies on tck -- 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 -- ticking and sel set. This means we are stuck with dmi_req up if
-- the jtag interface stops. Slaves must be resilient to this. -- the jtag interface stops. Slaves must be resilient to this.
-- --
if jtag_req = '1' and dmi_ack_1 = '1' then if jtag_req = '1' and dmi_ack_1 = '1' then
jtag_req <= '0'; jtag_req <= '0';
if request(1 downto 0) = DMI_REQ_RD then if request(1 downto 0) = DMI_REQ_RD then
request(DBITS + 1 downto 2) <= dmi_din; request(DBITS + 1 downto 2) <= dmi_din;
end if; end if;
end if; end if;


-- Capture state, grab latch content with updated status -- Capture state, grab latch content with updated status
if capture = '1' then if capture = '1' then
shiftr <= request(ABITS + DBITS + 1 downto 2) & rsp_op; shiftr <= request(ABITS + DBITS + 1 downto 2) & rsp_op;
end if; end if;


end if; end if;
end if; end if;
end process; end process;
end architecture behaviour; end architecture behaviour;



@ -8,11 +8,11 @@ entity clock_generator is
); );


port ( port (
ext_clk : in std_logic; ext_clk : in std_logic;
pll_rst_in : in std_logic; pll_rst_in : in std_logic;
pll_clk_out : out std_logic; pll_clk_out : out std_logic;
pll_locked_out : out std_logic pll_locked_out : out std_logic
); );


end entity clock_generator; end entity clock_generator;


@ -20,66 +20,66 @@ architecture bypass of clock_generator is


-- prototype of ECP5 PLL -- prototype of ECP5 PLL
component EHXPLLL is component EHXPLLL is
generic ( generic (
CLKI_DIV : integer := 1; CLKI_DIV : integer := 1;
CLKFB_DIV : integer := 1; CLKFB_DIV : integer := 1;
CLKOP_DIV : integer := 8; CLKOP_DIV : integer := 8;
CLKOS_DIV : integer := 8; CLKOS_DIV : integer := 8;
CLKOS2_DIV : integer := 8; CLKOS2_DIV : integer := 8;
CLKOS3_DIV : integer := 8; CLKOS3_DIV : integer := 8;
CLKOP_ENABLE : string := "ENABLED"; CLKOP_ENABLE : string := "ENABLED";
CLKOS_ENABLE : string := "DISABLED"; CLKOS_ENABLE : string := "DISABLED";
CLKOS2_ENABLE : string := "DISABLED"; CLKOS2_ENABLE : string := "DISABLED";
CLKOS3_ENABLE : string := "DISABLED"; CLKOS3_ENABLE : string := "DISABLED";
CLKOP_CPHASE : integer := 0; CLKOP_CPHASE : integer := 0;
CLKOS_CPHASE : integer := 0; CLKOS_CPHASE : integer := 0;
CLKOS2_CPHASE : integer := 0; CLKOS2_CPHASE : integer := 0;
CLKOS3_CPHASE : integer := 0; CLKOS3_CPHASE : integer := 0;
CLKOP_FPHASE : integer := 0; CLKOP_FPHASE : integer := 0;
CLKOS_FPHASE : integer := 0; CLKOS_FPHASE : integer := 0;
CLKOS2_FPHASE : integer := 0; CLKOS2_FPHASE : integer := 0;
CLKOS3_FPHASE : integer := 0; CLKOS3_FPHASE : integer := 0;
FEEDBK_PATH : string := "CLKOP"; FEEDBK_PATH : string := "CLKOP";
CLKOP_TRIM_POL : string := "RISING"; CLKOP_TRIM_POL : string := "RISING";
CLKOP_TRIM_DELAY : integer := 0; CLKOP_TRIM_DELAY : integer := 0;
CLKOS_TRIM_POL : string := "RISING"; CLKOS_TRIM_POL : string := "RISING";
CLKOS_TRIM_DELAY : integer := 0; CLKOS_TRIM_DELAY : integer := 0;
OUTDIVIDER_MUXA : string := "DIVA"; OUTDIVIDER_MUXA : string := "DIVA";
OUTDIVIDER_MUXB : string := "DIVB"; OUTDIVIDER_MUXB : string := "DIVB";
OUTDIVIDER_MUXC : string := "DIVC"; OUTDIVIDER_MUXC : string := "DIVC";
OUTDIVIDER_MUXD : string := "DIVD"; OUTDIVIDER_MUXD : string := "DIVD";
PLL_LOCK_MODE : integer := 0; PLL_LOCK_MODE : integer := 0;
PLL_LOCK_DELAY : integer := 200; PLL_LOCK_DELAY : integer := 200;
STDBY_ENABLE : string := "DISABLED"; STDBY_ENABLE : string := "DISABLED";
REFIN_RESET : string := "DISABLED"; REFIN_RESET : string := "DISABLED";
SYNC_ENABLE : string := "DISABLED"; SYNC_ENABLE : string := "DISABLED";
INT_LOCK_STICKY : string := "ENABLED"; INT_LOCK_STICKY : string := "ENABLED";
DPHASE_SOURCE : string := "DISABLED"; DPHASE_SOURCE : string := "DISABLED";
PLLRST_ENA : string := "DISABLED"; PLLRST_ENA : string := "DISABLED";
INTFB_WAKE : string := "DISABLED" ); INTFB_WAKE : string := "DISABLED" );
port ( port (
CLKI : in std_logic; CLKI : in std_logic;
CLKFB : in std_logic; CLKFB : in std_logic;
PHASESEL1 : in std_logic; PHASESEL1 : in std_logic;
PHASESEL0 : in std_logic; PHASESEL0 : in std_logic;
PHASEDIR : in std_logic; PHASEDIR : in std_logic;
PHASESTEP : in std_logic; PHASESTEP : in std_logic;
PHASELOADREG : in std_logic; PHASELOADREG : in std_logic;
STDBY : in std_logic; STDBY : in std_logic;
PLLWAKESYNC : in std_logic; PLLWAKESYNC : in std_logic;
RST : in std_logic; RST : in std_logic;
ENCLKOP : in std_logic; ENCLKOP : in std_logic;
ENCLKOS : in std_logic; ENCLKOS : in std_logic;
ENCLKOS2 : in std_logic; ENCLKOS2 : in std_logic;
ENCLKOS3 : in std_logic; ENCLKOS3 : in std_logic;
CLKOP : out std_logic; CLKOP : out std_logic;
CLKOS : out std_logic; CLKOS : out std_logic;
CLKOS2 : out std_logic; CLKOS2 : out std_logic;
CLKOS3 : out std_logic; CLKOS3 : out std_logic;
LOCK : out std_logic; LOCK : out std_logic;
INTLOCK : out std_logic; INTLOCK : out std_logic;
REFCLK : out std_logic; REFCLK : out std_logic;
CLKINTFB : out std_logic ); CLKINTFB : out std_logic );
end component; end component;


signal clkop : std_logic; signal clkop : std_logic;
@ -99,29 +99,29 @@ begin
pll_locked_out <= not lock; -- FIXME: EHXPLLL lock signal active low?!? pll_locked_out <= not lock; -- FIXME: EHXPLLL lock signal active low?!?


clkgen: EHXPLLL clkgen: EHXPLLL
generic map( generic map(
CLKOP_CPHASE => 11, -- FIXME: Copied from prjtrells. CLKOP_CPHASE => 11, -- FIXME: Copied from prjtrells.
CLKOP_DIV => PLL_CLKOP_DIV, CLKOP_DIV => PLL_CLKOP_DIV,
CLKFB_DIV => PLL_CLKFB_DIV, CLKFB_DIV => PLL_CLKFB_DIV,
CLKI_DIV => PLL_CLKI_DIV CLKI_DIV => PLL_CLKI_DIV
) )
port map ( port map (
CLKI => ext_clk, CLKI => ext_clk,
CLKOP => clkop, CLKOP => clkop,
CLKFB => clkop, CLKFB => clkop,
LOCK => lock, LOCK => lock,
RST => pll_rst_in, RST => pll_rst_in,
PHASESEL1 => '0', PHASESEL1 => '0',
PHASESEL0 => '0', PHASESEL0 => '0',
PHASEDIR => '0', PHASEDIR => '0',
PHASESTEP => '0', PHASESTEP => '0',
PHASELOADREG => '0', PHASELOADREG => '0',
STDBY => '0', STDBY => '0',
PLLWAKESYNC => '0', PLLWAKESYNC => '0',
ENCLKOP => '0', ENCLKOP => '0',
ENCLKOS => '0', ENCLKOS => '0',
ENCLKOS2 => '0', ENCLKOS2 => '0',
ENCLKOS3 => '0' ENCLKOS3 => '0'
); );


end architecture bypass; end architecture bypass;

@ -8,7 +8,7 @@ entity clock_generator is
generic ( generic (
CLK_INPUT_HZ : positive := 12000000; CLK_INPUT_HZ : positive := 12000000;
CLK_OUTPUT_HZ : positive := 50000000 CLK_OUTPUT_HZ : positive := 50000000
); );
port ( port (
ext_clk : in std_logic; ext_clk : in std_logic;
pll_rst_in : 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; clkfbout_mult : real range 2.0 to 64.0;
clkout_divide : real range 1.0 to 128.0; clkout_divide : real range 1.0 to 128.0;
divclk_divide : integer range 1 to 106; divclk_divide : integer range 1 to 106;
force_rst : std_ulogic; force_rst : std_ulogic;
end record; end record;


function gen_pll_settings ( function gen_pll_settings (
constant input_hz : positive; constant input_hz : positive;
constant output_hz : positive) constant output_hz : positive)
return pll_settings_t is return pll_settings_t is


constant bad_settings : pll_settings_t := constant bad_settings : pll_settings_t :=
(clkin_period => 0.0, (clkin_period => 0.0,
clkfbout_mult => 2.0, clkfbout_mult => 2.0,
clkout_divide => 1.0, clkout_divide => 1.0,
divclk_divide => 1, divclk_divide => 1,
force_rst => '1'); force_rst => '1');
begin begin
case input_hz is case input_hz is
when 100000000 => when 100000000 =>
case output_hz is case output_hz is
when 100000000 => when 100000000 =>
return (clkin_period => 10.0, return (clkin_period => 10.0,
clkfbout_mult => 16.0, clkfbout_mult => 16.0,
clkout_divide => 16.0, clkout_divide => 16.0,
divclk_divide => 1, divclk_divide => 1,
force_rst => '0'); force_rst => '0');
when 50000000 => when 50000000 =>
return (clkin_period => 10.0, return (clkin_period => 10.0,
clkfbout_mult => 16.0, clkfbout_mult => 16.0,
clkout_divide => 32.0, clkout_divide => 32.0,
divclk_divide => 1, divclk_divide => 1,
force_rst => '0'); force_rst => '0');
when others => when others =>
report "Unsupported output frequency" severity failure; report "Unsupported output frequency" severity failure;
return bad_settings; return bad_settings;
end case; end case;
when 12000000 => when 12000000 =>
case output_hz is case output_hz is
when 100000000 => when 100000000 =>
return (clkin_period => 83.33, return (clkin_period => 83.33,
clkfbout_mult => 50.0, clkfbout_mult => 50.0,
clkout_divide => 6.0, clkout_divide => 6.0,
divclk_divide => 1, divclk_divide => 1,
force_rst => '0'); force_rst => '0');
when 50000000 => when 50000000 =>
return (clkin_period => 83.33, return (clkin_period => 83.33,
clkfbout_mult => 50.0, clkfbout_mult => 50.0,
clkout_divide => 12.0, clkout_divide => 12.0,
divclk_divide => 1, divclk_divide => 1,
force_rst => '0'); force_rst => '0');
when others => when others =>
report "Unsupported output frequency" severity failure; report "Unsupported output frequency" severity failure;
return bad_settings; return bad_settings;
end case; end case;
when others => when others =>
report "Unsupported input frequency" severity failure; report "Unsupported input frequency" severity failure;
return bad_settings; return bad_settings;
end case; end case;
end function gen_pll_settings; end function gen_pll_settings;


constant pll_settings : pll_settings_t := gen_pll_settings(clk_input_hz, constant pll_settings : pll_settings_t := gen_pll_settings(clk_input_hz,
clk_output_hz); clk_output_hz);
begin begin
pll : MMCME2_BASE pll : MMCME2_BASE
generic map ( generic map (
@ -111,6 +111,6 @@ begin
CLKFBIN => clkfb, CLKFBIN => clkfb,
CLKIN1 => ext_clk, CLKIN1 => ext_clk,
PWRDWN => '0', PWRDWN => '0',
RST => pll_rst_in or pll_settings.force_rst RST => pll_rst_in or pll_settings.force_rst
); );
end architecture rtl; end architecture rtl;

@ -6,100 +6,100 @@ use UNISIM.vcomponents.all;


entity clock_generator is entity clock_generator is
generic ( generic (
CLK_INPUT_HZ : positive := 100000000; CLK_INPUT_HZ : positive := 100000000;
CLK_OUTPUT_HZ : positive := 100000000 CLK_OUTPUT_HZ : positive := 100000000
); );
port ( port (
ext_clk : in std_logic; ext_clk : in std_logic;
pll_rst_in : in std_logic; pll_rst_in : in std_logic;
pll_clk_out : out std_logic; pll_clk_out : out std_logic;
pll_locked_out : out std_logic); pll_locked_out : out std_logic);
end entity clock_generator; end entity clock_generator;


architecture rtl of clock_generator is architecture rtl of clock_generator is
signal clkfb : std_ulogic; signal clkfb : std_ulogic;


type pll_settings_t is record type pll_settings_t is record
clkin_period : real range 0.000 to 52.631; clkin_period : real range 0.000 to 52.631;
clkfbout_mult : integer range 2 to 64; clkfbout_mult : integer range 2 to 64;
clkout_divide : integer range 1 to 128; clkout_divide : integer range 1 to 128;
divclk_divide : integer range 1 to 56; divclk_divide : integer range 1 to 56;
force_rst : std_ulogic; force_rst : std_ulogic;
end record; end record;


function gen_pll_settings ( function gen_pll_settings (
constant input_hz : positive; constant input_hz : positive;
constant output_hz : positive) constant output_hz : positive)
return pll_settings_t is return pll_settings_t is


constant bad_settings : pll_settings_t := constant bad_settings : pll_settings_t :=
(clkin_period => 0.0, (clkin_period => 0.0,
clkfbout_mult => 2, clkfbout_mult => 2,
clkout_divide => 1, clkout_divide => 1,
divclk_divide => 1, divclk_divide => 1,
force_rst => '1'); force_rst => '1');
begin begin
case input_hz is case input_hz is
when 200000000 => when 200000000 =>
case output_hz is case output_hz is
when 100000000 => when 100000000 =>
return (clkin_period => 5.0, return (clkin_period => 5.0,
clkfbout_mult => 8, clkfbout_mult => 8,
clkout_divide => 16, clkout_divide => 16,
divclk_divide => 1, divclk_divide => 1,
force_rst => '0'); force_rst => '0');
when others => when others =>
report "Unsupported output frequency" severity failure; report "Unsupported output frequency" severity failure;
return bad_settings; return bad_settings;
end case; end case;
when 100000000 => when 100000000 =>
case output_hz is case output_hz is
when 100000000 => when 100000000 =>
return (clkin_period => 10.0, return (clkin_period => 10.0,
clkfbout_mult => 16, clkfbout_mult => 16,
clkout_divide => 16, clkout_divide => 16,
divclk_divide => 1, divclk_divide => 1,
force_rst => '0'); force_rst => '0');
when 50000000 => when 50000000 =>
return (clkin_period => 10.0, return (clkin_period => 10.0,
clkfbout_mult => 16, clkfbout_mult => 16,
clkout_divide => 32, clkout_divide => 32,
divclk_divide => 1, divclk_divide => 1,
force_rst => '0'); force_rst => '0');
when others => when others =>
report "Unsupported output frequency" severity failure; report "Unsupported output frequency" severity failure;
return bad_settings; return bad_settings;
end case; end case;
when others => when others =>
report "Unsupported input frequency" severity failure; report "Unsupported input frequency" severity failure;
return bad_settings; return bad_settings;
end case; end case;
end function gen_pll_settings; end function gen_pll_settings;


constant pll_settings : pll_settings_t := gen_pll_settings(clk_input_hz, constant pll_settings : pll_settings_t := gen_pll_settings(clk_input_hz,
clk_output_hz); clk_output_hz);
begin begin


pll : PLLE2_BASE pll : PLLE2_BASE
generic map ( generic map (
BANDWIDTH => "OPTIMIZED", BANDWIDTH => "OPTIMIZED",
CLKFBOUT_MULT => pll_settings.clkfbout_mult, CLKFBOUT_MULT => pll_settings.clkfbout_mult,
CLKIN1_PERIOD => pll_settings.clkin_period, CLKIN1_PERIOD => pll_settings.clkin_period,
CLKOUT0_DIVIDE => pll_settings.clkout_divide, CLKOUT0_DIVIDE => pll_settings.clkout_divide,
DIVCLK_DIVIDE => pll_settings.divclk_divide, DIVCLK_DIVIDE => pll_settings.divclk_divide,
STARTUP_WAIT => "FALSE") STARTUP_WAIT => "FALSE")
port map ( port map (
CLKOUT0 => pll_clk_out, CLKOUT0 => pll_clk_out,
CLKOUT1 => open, CLKOUT1 => open,
CLKOUT2 => open, CLKOUT2 => open,
CLKOUT3 => open, CLKOUT3 => open,
CLKOUT4 => open, CLKOUT4 => open,
CLKOUT5 => open, CLKOUT5 => open,
CLKFBOUT => clkfb, CLKFBOUT => clkfb,
LOCKED => pll_locked_out, LOCKED => pll_locked_out,
CLKIN1 => ext_clk, CLKIN1 => ext_clk,
PWRDWN => '0', PWRDWN => '0',
RST => pll_rst_in or pll_settings.force_rst, RST => pll_rst_in or pll_settings.force_rst,
CLKFBIN => clkfb); CLKFBIN => clkfb);


end architecture rtl; end architecture rtl;

@ -9,20 +9,20 @@ library work;


entity main_bram is entity main_bram is
generic( generic(
WIDTH : natural := 64; WIDTH : natural := 64;
HEIGHT_BITS : natural := 1024; HEIGHT_BITS : natural := 1024;
MEMORY_SIZE : natural := 65536; MEMORY_SIZE : natural := 65536;
RAM_INIT_FILE : string RAM_INIT_FILE : string
); );
port( port(
clk : in std_logic; clk : in std_logic;
addr : in std_logic_vector(HEIGHT_BITS - 1 downto 0) ; addr : in std_logic_vector(HEIGHT_BITS - 1 downto 0) ;
di : in std_logic_vector(WIDTH-1 downto 0); di : in std_logic_vector(WIDTH-1 downto 0);
do : out 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); sel : in std_logic_vector((WIDTH/8)-1 downto 0);
re : in std_ulogic; re : in std_ulogic;
we : in std_ulogic we : in std_ulogic
); );
end entity main_bram; end entity main_bram;


architecture behaviour of main_bram is architecture behaviour of main_bram is
@ -63,20 +63,20 @@ begin
-- Actual RAM template -- Actual RAM template
memory_0: process(clk) memory_0: process(clk)
begin begin
if rising_edge(clk) then if rising_edge(clk) then
if we = '1' then if we = '1' then
for i in 0 to 7 loop for i in 0 to 7 loop
if sel(i) = '1' then if sel(i) = '1' then
memory(to_integer(unsigned(addr)))((i + 1) * 8 - 1 downto i * 8) <= memory(to_integer(unsigned(addr)))((i + 1) * 8 - 1 downto i * 8) <=
di((i + 1) * 8 - 1 downto i * 8); di((i + 1) * 8 - 1 downto i * 8);
end if; end if;
end loop; end loop;
end if; end if;
if re = '1' then if re = '1' then
obuf <= memory(to_integer(unsigned(addr))); obuf <= memory(to_integer(unsigned(addr)));
end if; end if;
do <= obuf; do <= obuf;
end if; end if;
end process; end process;


end architecture behaviour; 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 entity main_bram is
generic( generic(
WIDTH : natural := 64; WIDTH : natural := 64;
HEIGHT_BITS : natural := 1024; HEIGHT_BITS : natural := 1024;
MEMORY_SIZE : natural := 65536; MEMORY_SIZE : natural := 65536;
RAM_INIT_FILE : string RAM_INIT_FILE : string
); );
port( port(
clk : in std_logic; clk : in std_logic;
addr : in std_logic_vector(HEIGHT_BITS - 1 downto 0) ; addr : in std_logic_vector(HEIGHT_BITS - 1 downto 0) ;
di : in std_logic_vector(WIDTH-1 downto 0); di : in std_logic_vector(WIDTH-1 downto 0);
do : out 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); sel : in std_logic_vector((WIDTH/8)-1 downto 0);
re : in std_ulogic; re : in std_ulogic;
we : in std_ulogic we : in std_ulogic
); );
end entity main_bram; end entity main_bram;


architecture sim of main_bram is architecture sim of main_bram is


constant WIDTH_BYTES : natural := WIDTH / 8; constant WIDTH_BYTES : natural := WIDTH / 8;
constant pad_zeros : std_ulogic_vector(log2(WIDTH_BYTES)-1 downto 0) 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, signal identifier : integer := behavioural_initialize(filename => RAM_INIT_FILE,
size => MEMORY_SIZE); size => MEMORY_SIZE);
-- Others -- Others
signal obuf : std_logic_vector(WIDTH-1 downto 0); signal obuf : std_logic_vector(WIDTH-1 downto 0);
begin begin


-- Actual RAM template -- Actual RAM template
memory_0: process(clk) memory_0: process(clk)
variable ret_dat_v : std_ulogic_vector(63 downto 0); variable ret_dat_v : std_ulogic_vector(63 downto 0);
variable addr64 : std_ulogic_vector(63 downto 0); variable addr64 : std_ulogic_vector(63 downto 0);
begin begin
if rising_edge(clk) then if rising_edge(clk) then
addr64 := (others => '0'); addr64 := (others => '0');
addr64(HEIGHT_BITS + 2 downto 3) := addr; addr64(HEIGHT_BITS + 2 downto 3) := addr;
if we = '1' then if we = '1' then
report "RAM writing " & to_hstring(di) & " to " & report "RAM writing " & to_hstring(di) & " to " &
to_hstring(addr & pad_zeros) & " sel:" & to_hstring(sel); to_hstring(addr & pad_zeros) & " sel:" & to_hstring(sel);
behavioural_write(di, addr64, to_integer(unsigned(sel)), identifier); behavioural_write(di, addr64, to_integer(unsigned(sel)), identifier);
end if; end if;
if re = '1' then if re = '1' then
behavioural_read(ret_dat_v, addr64, to_integer(unsigned(sel)), identifier); behavioural_read(ret_dat_v, addr64, to_integer(unsigned(sel)), identifier);
report "RAM reading from " & to_hstring(addr & pad_zeros) & report "RAM reading from " & to_hstring(addr & pad_zeros) &
" returns " & to_hstring(ret_dat_v); " returns " & to_hstring(ret_dat_v);
obuf <= ret_dat_v(obuf'left downto 0); obuf <= ret_dat_v(obuf'left downto 0);
end if; end if;
do <= obuf; do <= obuf;
end if; end if;
end process; end process;


end architecture sim; end architecture sim;

@ -6,30 +6,30 @@ library work;
use work.wishbone_types.all; use work.wishbone_types.all;


entity wishbone_debug_master is entity wishbone_debug_master is
port(clk : in std_ulogic; port(clk : in std_ulogic;
rst : in std_ulogic; rst : in std_ulogic;


-- Debug bus interface -- Debug bus interface
dmi_addr : in std_ulogic_vector(1 downto 0); dmi_addr : in std_ulogic_vector(1 downto 0);
dmi_din : in std_ulogic_vector(63 downto 0); dmi_din : in std_ulogic_vector(63 downto 0);
dmi_dout : out std_ulogic_vector(63 downto 0); dmi_dout : out std_ulogic_vector(63 downto 0);
dmi_req : in std_ulogic; dmi_req : in std_ulogic;
dmi_wr : in std_ulogic; dmi_wr : in std_ulogic;
dmi_ack : out std_ulogic; dmi_ack : out std_ulogic;


-- Wishbone master interface -- Wishbone master interface
wb_out : out wishbone_master_out; wb_out : out wishbone_master_out;
wb_in : in wishbone_slave_out wb_in : in wishbone_slave_out
); );
end entity wishbone_debug_master; end entity wishbone_debug_master;


architecture behaviour of wishbone_debug_master is architecture behaviour of wishbone_debug_master is


-- ** Register offsets definitions. All registers are 64-bit -- ** Register offsets definitions. All registers are 64-bit
constant DBG_WB_ADDR : std_ulogic_vector(1 downto 0) := "00"; 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_DATA : std_ulogic_vector(1 downto 0) := "01";
constant DBG_WB_CTRL : std_ulogic_vector(1 downto 0) := "10"; 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_RSVD : std_ulogic_vector(1 downto 0) := "11";


-- CTRL register: -- CTRL register:
-- --
@ -42,10 +42,10 @@ architecture behaviour of wishbone_debug_master is
-- 11 - +8 -- 11 - +8


-- ** Address and control registers and read data -- ** Address and control registers and read data
signal reg_addr : 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_out : std_ulogic_vector(63 downto 0);
signal reg_ctrl : std_ulogic_vector(10 downto 0); signal reg_ctrl : std_ulogic_vector(10 downto 0);
signal data_latch : std_ulogic_vector(63 downto 0); signal data_latch : std_ulogic_vector(63 downto 0);
type state_t is (IDLE, WB_CYCLE, DMI_WAIT); type state_t is (IDLE, WB_CYCLE, DMI_WAIT);
signal state : state_t; signal state : state_t;
@ -55,49 +55,49 @@ begin


-- Hard wire unused bits to 0 -- Hard wire unused bits to 0
reg_ctrl_out <= (63 downto 11 => '0', reg_ctrl_out <= (63 downto 11 => '0',
10 downto 0 => reg_ctrl); 10 downto 0 => reg_ctrl);


-- DMI read data mux -- DMI read data mux
with dmi_addr select dmi_dout <= with dmi_addr select dmi_dout <=
reg_addr when DBG_WB_ADDR, reg_addr when DBG_WB_ADDR,
data_latch when DBG_WB_DATA, data_latch when DBG_WB_DATA,
reg_ctrl_out when DBG_WB_CTRL, reg_ctrl_out when DBG_WB_CTRL,
(others => '0') when others; (others => '0') when others;


-- ADDR and CTRL register writes -- ADDR and CTRL register writes
reg_write : process(clk) reg_write : process(clk)
subtype autoinc_inc_t is integer range 1 to 8; subtype autoinc_inc_t is integer range 1 to 8;
function decode_autoinc(c : std_ulogic_vector(1 downto 0)) function decode_autoinc(c : std_ulogic_vector(1 downto 0))
return autoinc_inc_t is return autoinc_inc_t is
begin begin
case c is case c is
when "00" => return 1; when "00" => return 1;
when "01" => return 2; when "01" => return 2;
when "10" => return 4; when "10" => return 4;
when "11" => return 8; when "11" => return 8;
-- Below shouldn't be necessary but GHDL complains -- Below shouldn't be necessary but GHDL complains
when others => return 8; when others => return 8;
end case; end case;
end function decode_autoinc; end function decode_autoinc;
begin begin
if rising_edge(clk) then if rising_edge(clk) then
if (rst) then if (rst) then
reg_addr <= (others => '0'); reg_addr <= (others => '0');
reg_ctrl <= (others => '0'); reg_ctrl <= (others => '0');
else -- Standard register writes else -- Standard register writes
if do_inc = '1' then if do_inc = '1' then
-- Address register auto-increment -- Address register auto-increment
reg_addr <= std_ulogic_vector(unsigned(reg_addr) + reg_addr <= std_ulogic_vector(unsigned(reg_addr) +
decode_autoinc(reg_ctrl(10 downto 9))); decode_autoinc(reg_ctrl(10 downto 9)));
elsif dmi_req and dmi_wr then elsif dmi_req and dmi_wr then
if dmi_addr = DBG_WB_ADDR then if dmi_addr = DBG_WB_ADDR then
reg_addr <= dmi_din; reg_addr <= dmi_din;
elsif dmi_addr = DBG_WB_CTRL then elsif dmi_addr = DBG_WB_CTRL then
reg_ctrl <= dmi_din(10 downto 0); reg_ctrl <= dmi_din(10 downto 0);
end if; end if;
end if; end if;
end if; end if;
end if; end if;
end process; end process;


-- ACK is hard wired to req for register writes. For data read/writes -- 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'; 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.adr <= reg_addr(wb_out.adr'left downto 0);
wb_out.dat <= dmi_din; wb_out.dat <= dmi_din;
wb_out.sel <= reg_ctrl(7 downto 0); wb_out.sel <= reg_ctrl(7 downto 0);
@ -132,47 +132,47 @@ begin
-- --
latch_reads : process(clk) latch_reads : process(clk)
begin begin
if rising_edge(clk) then if rising_edge(clk) then
if state = WB_CYCLE and wb_in.ack = '1' and dmi_wr = '0' then if state = WB_CYCLE and wb_in.ack = '1' and dmi_wr = '0' then
data_latch <= wb_in.dat; data_latch <= wb_in.dat;
end if; end if;
end if; end if;
end process; end process;


-- Command state machine (generate wb_cyc) -- Command state machine (generate wb_cyc)
wb_trigger : process(clk) wb_trigger : process(clk)
begin begin
if rising_edge(clk) then if rising_edge(clk) then
if (rst) then if (rst) then
state <= IDLE; state <= IDLE;
wb_out.stb <= '0'; wb_out.stb <= '0';
do_inc <= '0'; do_inc <= '0';
else else
case state is case state is
when IDLE => when IDLE =>
if dmi_req = '1' and dmi_addr = DBG_WB_DATA then if dmi_req = '1' and dmi_addr = DBG_WB_DATA then
state <= WB_CYCLE; state <= WB_CYCLE;
wb_out.stb <= '1'; wb_out.stb <= '1';
end if; end if;
when WB_CYCLE => when WB_CYCLE =>
if wb_in.stall = '0' then if wb_in.stall = '0' then
wb_out.stb <= '0'; wb_out.stb <= '0';
end if; end if;
if wb_in.ack then if wb_in.ack then
-- We shouldn't get the ack if we hadn't already cleared -- We shouldn't get the ack if we hadn't already cleared
-- stb above but if this happen, don't leave it dangling. -- stb above but if this happen, don't leave it dangling.
-- --
wb_out.stb <= '0'; wb_out.stb <= '0';
state <= DMI_WAIT; state <= DMI_WAIT;
do_inc <= reg_ctrl(8); do_inc <= reg_ctrl(8);
end if; end if;
when DMI_WAIT => when DMI_WAIT =>
if dmi_req = '0' then if dmi_req = '0' then
state <= IDLE; state <= IDLE;
end if; end if;
do_inc <= '0'; do_inc <= '0';
end case; end case;
end if; end if;
end if; end if;
end process; end process;
end architecture behaviour; end architecture behaviour;

@ -32,25 +32,25 @@ entity xics_icp is
wb_in : in wb_io_master_out; wb_in : in wb_io_master_out;
wb_out : out wb_io_slave_out; wb_out : out wb_io_slave_out;


ics_in : in ics_to_icp_t; ics_in : in ics_to_icp_t;
core_irq_out : out std_ulogic core_irq_out : out std_ulogic
); );
end xics_icp; end xics_icp;


architecture behaviour of xics_icp is architecture behaviour of xics_icp is
type reg_internal_t is record type reg_internal_t is record
xisr : std_ulogic_vector(23 downto 0); xisr : std_ulogic_vector(23 downto 0);
cppr : std_ulogic_vector(7 downto 0); cppr : std_ulogic_vector(7 downto 0);
mfrr : std_ulogic_vector(7 downto 0); mfrr : std_ulogic_vector(7 downto 0);
irq : std_ulogic; irq : std_ulogic;
wb_rd_data : std_ulogic_vector(31 downto 0); wb_rd_data : std_ulogic_vector(31 downto 0);
wb_ack : std_ulogic; wb_ack : std_ulogic;
end record; end record;
constant reg_internal_init : reg_internal_t := constant reg_internal_init : reg_internal_t :=
(wb_ack => '0', (wb_ack => '0',
mfrr => x"ff", -- mask everything on reset mfrr => x"ff", -- mask everything on reset
irq => '0', irq => '0',
others => (others => '0')); others => (others => '0'));


signal r, r_next : reg_internal_t; signal r, r_next : reg_internal_t;


@ -67,12 +67,12 @@ begin


regs : process(clk) regs : process(clk)
begin begin
if rising_edge(clk) then if rising_edge(clk) then
r <= r_next; r <= r_next;


-- We delay core_irq_out by a cycle to help with timing -- We delay core_irq_out by a cycle to help with timing
core_irq_out <= r.irq; core_irq_out <= r.irq;
end if; end if;
end process; end process;


wb_out.dat <= r.wb_rd_data; wb_out.dat <= r.wb_rd_data;
@ -80,8 +80,8 @@ begin
wb_out.stall <= '0'; -- never stall wishbone wb_out.stall <= '0'; -- never stall wishbone


comb : process(all) comb : process(all)
variable v : reg_internal_t; variable v : reg_internal_t;
variable xirr_accept_rd : std_ulogic; variable xirr_accept_rd : std_ulogic;


function bswap(v : in std_ulogic_vector(31 downto 0)) return std_ulogic_vector is function bswap(v : in std_ulogic_vector(31 downto 0)) return std_ulogic_vector is
variable r : std_ulogic_vector(31 downto 0); variable r : std_ulogic_vector(31 downto 0);
@ -96,65 +96,65 @@ begin
variable be_in : std_ulogic_vector(31 downto 0); variable be_in : std_ulogic_vector(31 downto 0);
variable be_out : 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 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_in := bswap(wb_in.dat);
be_out := (others => '0'); be_out := (others => '0');


if wb_in.cyc = '1' and wb_in.stb = '1' then if wb_in.cyc = '1' and wb_in.stb = '1' then
v.wb_ack := '1'; -- always ack v.wb_ack := '1'; -- always ack
if wb_in.we = '1' then -- write if wb_in.we = '1' then -- write
-- writes to both XIRR are the same -- writes to both XIRR are the same
case wb_in.adr(7 downto 0) is case wb_in.adr(7 downto 0) is
when XIRR_POLL => when XIRR_POLL =>
report "ICP XIRR_POLL write"; report "ICP XIRR_POLL write";
v.cppr := be_in(31 downto 24); v.cppr := be_in(31 downto 24);
when XIRR => when XIRR =>
v.cppr := be_in(31 downto 24); 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); 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)); report "ICP XIRR write byte (CPPR):" & to_hstring(be_in(31 downto 24));
else else
report "ICP XIRR UNSUPPORTED write ! sel=" & to_hstring(wb_in.sel); report "ICP XIRR UNSUPPORTED write ! sel=" & to_hstring(wb_in.sel);
end if; end if;
when MFRR => when MFRR =>
v.mfrr := be_in(31 downto 24); 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); 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)); report "ICP MFRR write byte:" & to_hstring(be_in(31 downto 24));
else else
report "ICP MFRR UNSUPPORTED write ! sel=" & to_hstring(wb_in.sel); report "ICP MFRR UNSUPPORTED write ! sel=" & to_hstring(wb_in.sel);
end if; end if;
when others => 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 => when XIRR_POLL =>
report "ICP XIRR_POLL read"; report "ICP XIRR_POLL read";
be_out := r.cppr & r.xisr; be_out := r.cppr & r.xisr;
when XIRR => when XIRR =>
report "ICP XIRR read"; report "ICP XIRR read";
be_out := r.cppr & r.xisr; be_out := r.cppr & r.xisr;
if wb_in.sel = x"f" then if wb_in.sel = x"f" then
xirr_accept_rd := '1'; xirr_accept_rd := '1';
end if; end if;
when MFRR => when MFRR =>
report "ICP MFRR read"; report "ICP MFRR read";
be_out(31 downto 24) := r.mfrr; be_out(31 downto 24) := r.mfrr;
when others => when others =>
end case; end case;
end if; end if;
end if; end if;


pending_priority := x"ff"; pending_priority := x"ff";
v.xisr := x"000000"; v.xisr := x"000000";
@ -171,14 +171,14 @@ begin
pending_priority := r.mfrr; pending_priority := r.mfrr;
end if; end if;


-- Accept the interrupt -- Accept the interrupt
if xirr_accept_rd = '1' then if xirr_accept_rd = '1' then
report "XICS: ICP ACCEPT" & report "XICS: ICP ACCEPT" &
" cppr:" & to_hstring(r.cppr) & " cppr:" & to_hstring(r.cppr) &
" xisr:" & to_hstring(r.xisr) & " xisr:" & to_hstring(r.xisr) &
" mfrr:" & to_hstring(r.mfrr); " mfrr:" & to_hstring(r.mfrr);
v.cppr := pending_priority; v.cppr := pending_priority;
end if; end if;


v.wb_rd_data := bswap(be_out); v.wb_rd_data := bswap(be_out);


@ -191,11 +191,11 @@ begin
report "IRQ clr"; report "IRQ clr";
end if; end if;


if rst = '1' then if rst = '1' then
v := reg_internal_init; v := reg_internal_init;
end if; end if;


r_next <= v; r_next <= v;


end process; end process;


@ -221,8 +221,8 @@ entity xics_ics is
wb_in : in wb_io_master_out; wb_in : in wb_io_master_out;
wb_out : out wb_io_slave_out; wb_out : out wb_io_slave_out;


int_level_in : in std_ulogic_vector(SRC_NUM - 1 downto 0); int_level_in : in std_ulogic_vector(SRC_NUM - 1 downto 0);
icp_out : out ics_to_icp_t icp_out : out ics_to_icp_t
); );
end xics_ics; end xics_ics;



Loading…
Cancel
Save