mirror of
https://github.com/antonblanchard/microwatt.git
synced 2026-01-11 23:43:15 +00:00
Fix some whitespace issues
Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
This commit is contained in:
parent
46cde3bb23
commit
7994b98404
180
core_debug.vhdl
180
core_debug.vhdl
@ -12,25 +12,25 @@ entity core_debug is
|
|||||||
LOG_LENGTH : natural := 512
|
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;
|
||||||
|
|||||||
1504
ppc_fx_insns.vhdl
1504
ppc_fx_insns.vhdl
File diff suppressed because it is too large
Load Diff
@ -13,55 +13,55 @@ use work.sim_bram_helpers.all;
|
|||||||
|
|
||||||
entity main_bram is
|
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;
|
||||||
|
|||||||
108
xics.vhdl
108
xics.vhdl
@ -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…
x
Reference in New Issue
Block a user