GHDL=ghdl
-GHDLFLAGS=--std=08
+GHDLFLAGS=--std=08 -Psim-unisim
CFLAGS=-O2 -Wall
-all = core_tb simple_ram_behavioural_tb soc_reset_tb icache_tb multiply_tb
+all = core_tb simple_ram_behavioural_tb soc_reset_tb icache_tb multiply_tb dmi_dtm_tb
+
# XXX
# loadstore_tb fetch_tb
simple_ram_behavioural_tb.o: wishbone_types.o simple_ram_behavioural.o
simple_ram_behavioural.o: wishbone_types.o simple_ram_behavioural_helpers.o
sim_uart.o: wishbone_types.o sim_console.o
-soc.o: common.o wishbone_types.o core.o wishbone_arbiter.o sim_uart.o simple_ram_behavioural.o
+soc.o: common.o wishbone_types.o core.o wishbone_arbiter.o sim_uart.o simple_ram_behavioural.o dmi_dtm_xilinx.o
wishbone_arbiter.o: wishbone_types.o
wishbone_types.o:
writeback.o: common.o
+dmi_dtm_tb.o: dmi_dtm_xilinx.o
+dmi_dtm_xilinx.o: sim-unisim/unisim_vcomponents.o
+
+UNISIM_BITS = sim-unisim/unisim_vcomponents.vhdl sim-unisim/BSCANE2.vhdl sim-unisim/BUFG.vhdl
+sim-unisim/unisim_vcomponents.o: $(UNISIM_BITS)
+ $(GHDL) -a $(GHDLFLAGS) --work=unisim --workdir=sim-unisim $^
+
+
fpga/soc_reset_tb.o: fpga/soc_reset.o
soc_reset_tb: fpga/soc_reset_tb.o fpga/soc_reset.o
simple_ram_behavioural_tb: simple_ram_behavioural_helpers_c.o simple_ram_behavioural_tb.o
$(GHDL) -e $(GHDLFLAGS) -Wl,simple_ram_behavioural_helpers_c.o $@
+dmi_dtm_tb: dmi_dtm_tb.o
+ $(GHDL) -e $(GHDLFLAGS) $@
+
tests = $(sort $(patsubst tests/%.out,%,$(wildcard tests/*.out)))
check: $(tests) test_micropython test_micropython_long
@./scripts/test_micropython_long.py
clean:
- rm -f *.o work-*cf $(all)
+ rm -f *.o work-*cf unisim-*cf $(all)
+ rm -f sim-unisim/*.o sim-unisim/unisim-*cf
--- /dev/null
+-- Dummy/empty DMI interface to make toplevel happy on unsupported FPGAs
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+library work;
+use work.wishbone_types.all;
+
+entity dmi_dtm is
+ generic(ABITS : INTEGER:=8;
+ DBITS : INTEGER:=32);
+
+ port(sys_clk : in std_ulogic;
+ sys_reset : in std_ulogic;
+ dmi_addr : out std_ulogic_vector(ABITS - 1 downto 0);
+ dmi_din : in std_ulogic_vector(DBITS - 1 downto 0);
+ dmi_dout : out std_ulogic_vector(DBITS - 1 downto 0);
+ dmi_req : out std_ulogic;
+ dmi_wr : out std_ulogic;
+ dmi_ack : in std_ulogic
+ );
+end entity dmi_dtm;
+
+architecture behaviour of dmi_dtm is
+ dmi_addr <= (others => '0');
+ dmi_dout <= (others => '0');
+ dmi_req <= '0';
+ dmi_wr <= '0';
+end architecture behaviour;
+
--- /dev/null
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.common.all;
+use work.wishbone_types.all;
+
+library unisim;
+use unisim.vcomponents.all;
+
+entity dmi_dtm_tb is
+end dmi_dtm_tb;
+
+architecture behave of dmi_dtm_tb is
+ signal clk : std_ulogic;
+ signal rst : std_ulogic;
+ constant clk_period : time := 10 ns;
+ constant jclk_period : time := 30 ns;
+
+ -- DMI debug bus signals
+ signal dmi_addr : std_ulogic_vector(7 downto 0);
+ signal dmi_din : std_ulogic_vector(63 downto 0);
+ signal dmi_dout : std_ulogic_vector(63 downto 0);
+ signal dmi_req : std_ulogic;
+ signal dmi_wr : std_ulogic;
+ signal dmi_ack : std_ulogic;
+
+ -- Global JTAG signals (used by BSCANE2 inside dmi_dtm
+ alias j : glob_jtag_t is glob_jtag;
+
+ -- Wishbone interfaces
+ signal wishbone_ram_in : wishbone_slave_out;
+ signal wishbone_ram_out : wishbone_master_out;
+
+begin
+ dtm: entity work.dmi_dtm
+ generic map(
+ ABITS => 8,
+ DBITS => 64
+ )
+ port map(
+ sys_clk => clk,
+ sys_reset => rst,
+ dmi_addr => dmi_addr,
+ dmi_din => dmi_din,
+ dmi_dout => dmi_dout,
+ dmi_req => dmi_req,
+ dmi_wr => dmi_wr,
+ dmi_ack => dmi_ack
+ );
+
+ -- Dummy loopback until a debug module is present
+ dmi_din <= dmi_dout;
+ dmi_ack <= dmi_ack;
+
+ -- system clock
+ sys_clk: process
+ begin
+ clk <= '1';
+ wait for clk_period / 2;
+ clk <= '0';
+ wait for clk_period / 2;
+ end process sys_clk;
+
+ -- system sim: just reset and wait
+ sys_sim: process
+ begin
+ rst <= '1';
+ wait for clk_period;
+ rst <= '0';
+ wait;
+ end process;
+
+ -- jtag sim process
+ sim_jtag: process
+ procedure clock(count: in INTEGER) is
+ begin
+ for i in 1 to count loop
+ j.tck <= '0';
+ wait for jclk_period/2;
+ j.tck <= '1';
+ wait for jclk_period/2;
+ end loop;
+ end procedure clock;
+
+ procedure shift_out(val: in std_ulogic_vector) is
+ begin
+ for i in 0 to val'length-1 loop
+ j.tdi <= val(i);
+ clock(1);
+ end loop;
+ end procedure shift_out;
+
+ procedure shift_in(val: out std_ulogic_vector) is
+ begin
+ for i in val'length-1 downto 0 loop
+ val := j.tdo & val(val'length-1 downto 1);
+ clock(1);
+ end loop;
+ end procedure shift_in;
+
+ procedure send_command(
+ addr : in std_ulogic_vector(7 downto 0);
+ data : in std_ulogic_vector(63 downto 0);
+ op : in std_ulogic_vector(1 downto 0)) is
+ begin
+ j.capture <= '1';
+ clock(1);
+ j.capture <= '0';
+ clock(1);
+ j.shift <= '1';
+ shift_out(op);
+ shift_out(data);
+ shift_out(addr);
+ j.shift <= '0';
+ j.update <= '1';
+ clock(1);
+ j.update <= '0';
+ clock(1);
+ end procedure send_command;
+
+ procedure read_resp(
+ op : out std_ulogic_vector(1 downto 0);
+ data : out std_ulogic_vector(63 downto 0)) is
+
+ variable addr : std_ulogic_vector(7 downto 0);
+ begin
+ j.capture <= '1';
+ clock(1);
+ j.capture <= '0';
+ clock(1);
+ j.shift <= '1';
+ shift_in(op);
+ shift_in(data);
+ shift_in(addr);
+ j.shift <= '0';
+ j.update <= '1';
+ clock(1);
+ j.update <= '0';
+ clock(1);
+ end procedure read_resp;
+
+ procedure dmi_write(addr : in std_ulogic_vector(7 downto 0);
+ data : in std_ulogic_vector(63 downto 0)) is
+ variable resp_op : std_ulogic_vector(1 downto 0);
+ variable resp_data : std_ulogic_vector(63 downto 0);
+ variable timeout : integer;
+ begin
+ send_command(addr, data, "10");
+ loop
+ read_resp(resp_op, resp_data);
+ case resp_op is
+ when "00" =>
+ return;
+ when "11" =>
+ timeout := timeout + 1;
+ assert timeout < 0
+ report "dmi_write timed out !" severity error;
+ when others =>
+ assert 0 > 1 report "dmi_write got odd status: " &
+ to_hstring(resp_op) severity error;
+ end case;
+ end loop;
+ end procedure dmi_write;
+
+
+ procedure dmi_read(addr : in std_ulogic_vector(7 downto 0);
+ data : out std_ulogic_vector(63 downto 0)) is
+ variable resp_op : std_ulogic_vector(1 downto 0);
+ variable timeout : integer;
+ begin
+ send_command(addr, (others => '0'), "01");
+ loop
+ read_resp(resp_op, data);
+ case resp_op is
+ when "00" =>
+ return;
+ when "11" =>
+ timeout := timeout + 1;
+ assert timeout < 0
+ report "dmi_read timed out !" severity error;
+ when others =>
+ assert 0 > 1 report "dmi_read got odd status: " &
+ to_hstring(resp_op) severity error;
+ end case;
+ end loop;
+ end procedure dmi_read;
+
+ variable data : std_ulogic_vector(63 downto 0);
+ begin
+ -- init & reset
+ j.reset <= '1';
+ j.sel <= "0000";
+ j.capture <= '0';
+ j.update <= '0';
+ j.shift <= '0';
+ j.tdi <= '0';
+ j.tms <= '0';
+ j.runtest <= '0';
+ clock(5);
+ j.reset <= '0';
+ clock(5);
+
+ -- select chain 2
+ j.sel <= "0010";
+ clock(1);
+
+ -- send command
+ dmi_read(x"00", data);
+ report "Read addr reg:" & to_hstring(data);
+ std.env.finish;
+ end process;
+end behave;
--- /dev/null
+-- Xilinx internal JTAG to DMI interface
+--
+-- DMI bus
+--
+-- req : ____/------------\_____
+-- addr: xxxx< >xxxxx
+-- dout: xxxx< >xxxxx
+-- wr : xxxx< >xxxxx
+-- din : xxxxxxxxxxxx< >xxx
+-- ack : ____________/------\___
+--
+-- * addr/dout set along with req, can be latched on same cycle by slave
+-- * ack & din remain up until req is dropped by master, the slave must
+-- provide a stable output on din on reads during that time.
+-- * req remains low at until at least one sysclk after ack seen down.
+--
+-- JTAG (tck) DMI (sys_clk)
+--
+-- * jtag_req = 1
+-- (jtag_req_0) *
+-- (jtag_req_1) -> * dmi_req = 1 >
+-- *.../...
+-- * dmi_ack = 1 <
+-- * (dmi_ack_0)
+-- * <- (dmi_ack_1)
+-- * jtag_req = 0 (and latch dmi_din)
+-- (jtag_req_0) *
+-- (jtag_req_1) -> * dmi_req = 0 >
+-- * dmi_ack = 0 <
+-- * (dmi_ack_0)
+-- * <- (dmi_ack_1)
+--
+-- jtag_req can go back to 1 when jtag_rsp_1 is 0
+--
+-- Questions/TODO:
+-- - I use 2 flip fops for sync, is that enough ?
+-- - I treat the jtag_reset as an async reset, is that necessary ?
+-- - Dbl check reset situation since we have two different resets
+-- each only resetting part of the logic...
+-- - Look at optionally removing the synchronizer on the ack path,
+-- assuming JTAG is always slow enough that ack will have been
+-- stable long enough by the time CAPTURE comes in.
+-- - We could avoid the latched request by not shifting while a
+-- request is in progress (and force TDO to 1 to return a busy
+-- status).
+--
+-- WARNING: This isn't the real DMI JTAG protocol (at least not yet).
+-- a command while busy will be ignored. A response of "11"
+-- means the previous command is still going, try again.
+-- As such We don't implement the DMI "error" status, and
+-- we don't implement DTMCS yet... This may still all change
+-- but for now it's easier that way as the real DMI protocol
+-- requires for a command to work properly that enough TCK
+-- are sent while IDLE and I'm having trouble getting that
+-- working with UrJtag and the Xilinx BSCAN2 for now.
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.math_real.all;
+
+library work;
+use work.wishbone_types.all;
+
+library unisim;
+use unisim.vcomponents.all;
+
+entity dmi_dtm is
+ generic(ABITS : INTEGER:=8;
+ DBITS : INTEGER:=32);
+
+ port(sys_clk : in std_ulogic;
+ sys_reset : in std_ulogic;
+ dmi_addr : out std_ulogic_vector(ABITS - 1 downto 0);
+ dmi_din : in std_ulogic_vector(DBITS - 1 downto 0);
+ dmi_dout : out std_ulogic_vector(DBITS - 1 downto 0);
+ dmi_req : out std_ulogic;
+ dmi_wr : out std_ulogic;
+ dmi_ack : in std_ulogic
+-- dmi_err : in std_ulogic TODO: Add error response
+ );
+end entity dmi_dtm;
+
+architecture behaviour of dmi_dtm is
+
+ -- Signals coming out of the BSCANE2 block
+ signal jtag_reset : std_ulogic;
+ signal capture : std_ulogic;
+ signal update : std_ulogic;
+ signal drck : std_ulogic;
+ signal jtag_clk : std_ulogic;
+ signal sel : std_ulogic;
+ signal shift : std_ulogic;
+ signal tdi : std_ulogic;
+ signal tdo : std_ulogic;
+ signal tck : std_ulogic;
+
+ -- ** JTAG clock domain **
+
+ -- Shift register
+ signal shiftr : std_ulogic_vector(ABITS + DBITS + 1 downto 0);
+
+ -- Latched request
+ signal request : std_ulogic_vector(ABITS + DBITS + 1 downto 0);
+
+ -- A request is present
+ signal jtag_req : std_ulogic;
+
+ -- Synchronizer for jtag_rsp (sys clk -> jtag_clk)
+ signal dmi_ack_0 : std_ulogic;
+ signal dmi_ack_1 : std_ulogic;
+
+ -- ** sys clock domain **
+
+ -- Synchronizer for jtag_req (jtag clk -> sys clk)
+ signal jtag_req_0 : std_ulogic;
+ signal jtag_req_1 : std_ulogic;
+
+ -- ** combination signals
+ signal jtag_bsy : std_ulogic;
+ signal op_valid : std_ulogic;
+ signal rsp_op : std_ulogic_vector(1 downto 0);
+
+ -- ** Constants **
+ constant DMI_REQ_NOP : std_ulogic_vector(1 downto 0) := "00";
+ constant DMI_REQ_RD : std_ulogic_vector(1 downto 0) := "01";
+ constant DMI_REQ_WR : std_ulogic_vector(1 downto 0) := "10";
+ constant DMI_RSP_OK : std_ulogic_vector(1 downto 0) := "00";
+ constant DMI_RSP_BSY : std_ulogic_vector(1 downto 0) := "11";
+
+begin
+
+ -- Implement the Xilinx bscan2 for series 7 devices (TODO: use PoC to
+ -- wrap this if compatibility is required with older devices).
+ bscan : BSCANE2
+ generic map (
+ JTAG_CHAIN => 2
+ )
+ port map (
+ CAPTURE => capture,
+ DRCK => drck,
+ RESET => jtag_reset,
+ RUNTEST => open,
+ SEL => sel,
+ SHIFT => shift,
+ TCK => tck,
+ TDI => tdi,
+ TMS => open,
+ UPDATE => update,
+ TDO => tdo
+ );
+
+ -- Some examples out there suggest buffering the clock so it's
+ -- treated as a proper clock net. This is probably needed when using
+ -- drck (the gated clock) but I'm using the real tck here to avoid
+ -- missing the update phase so maybe not...
+ --
+ clkbuf : BUFG
+ port map (
+-- I => drck,
+ I => tck,
+ O => jtag_clk
+ );
+
+
+ -- dmi_req synchronization
+ dmi_req_sync : process(sys_clk)
+ begin
+ -- sys_reset is synchronous
+ if rising_edge(sys_clk) then
+ if (sys_reset = '1') then
+ jtag_req_0 <= '0';
+ jtag_req_1 <= '0';
+ else
+ jtag_req_0 <= jtag_req;
+ jtag_req_1 <= jtag_req_0;
+ end if;
+ end if;
+ end process;
+ dmi_req <= jtag_req_1;
+
+ -- dmi_ack synchronization
+ dmi_ack_sync: process(jtag_clk, jtag_reset)
+ begin
+ -- jtag_reset is async (see comments)
+ if jtag_reset = '1' then
+ dmi_ack_0 <= '0';
+ dmi_ack_1 <= '0';
+ elsif rising_edge(jtag_clk) then
+ dmi_ack_0 <= dmi_ack;
+ dmi_ack_1 <= dmi_ack_0;
+ end if;
+ end process;
+
+ -- jtag_bsy indicates whether we can start a new request, we can when
+ -- we aren't already processing one (jtag_req) and the synchronized ack
+ -- of the previous one is 0.
+ --
+ jtag_bsy <= jtag_req or dmi_ack_1;
+
+ -- decode request type in shift register
+ with shiftr(1 downto 0) select op_valid <=
+ '1' when DMI_REQ_RD,
+ '1' when DMI_REQ_WR,
+ '0' when others;
+
+ -- encode response op
+ rsp_op <= DMI_RSP_BSY when jtag_bsy = '1' else DMI_RSP_OK;
+
+ -- Some DMI out signals are directly driven from the request register
+ dmi_addr <= request(ABITS + DBITS + 1 downto DBITS + 2);
+ dmi_dout <= request(DBITS + 1 downto 2);
+ dmi_wr <= '1' when request(1 downto 0) = DMI_REQ_WR else '0';
+
+ -- TDO is wired to shift register bit 0
+ tdo <= shiftr(0);
+
+ -- Main state machine. Handles shift registers, request latch and
+ -- jtag_req latch. Could be split into 3 processes but it's probably
+ -- not worthwhile.
+ --
+ shifter: process(jtag_clk, jtag_reset)
+ begin
+ if jtag_reset = '1' then
+ shiftr <= (others => '0');
+ request <= (others => '0');
+ jtag_req <= '0';
+ elsif rising_edge(jtag_clk) then
+
+ -- Handle jtag "commands" when sel is 1
+ if sel = '1' then
+ -- Shift state, rotate the register
+ if shift = '1' then
+ shiftr <= tdi & shiftr(ABITS + DBITS + 1 downto 1);
+ end if;
+
+ -- Update state (trigger)
+ --
+ -- Latch the request if we aren't already processing one and
+ -- it has a valid command opcode.
+ --
+ if update = '1' and op_valid = '1' then
+ if jtag_bsy = '0' then
+ request <= shiftr;
+ jtag_req <= '1';
+ end if;
+ -- Set the shift register "op" to "busy". This will prevent
+ -- us from re-starting the command on the next update if
+ -- the command completes before that.
+ shiftr(1 downto 0) <= DMI_RSP_BSY;
+ end if;
+
+ -- Request completion.
+ --
+ -- Capture the response data for reads and clear request flag.
+ --
+ -- Note: We clear req (and thus dmi_req) here which relies on tck
+ -- ticking and sel set. This means we are stuck with dmi_req up if
+ -- the jtag interface stops. Slaves must be resilient to this.
+ --
+ if jtag_req = '1' and dmi_ack_1 = '1' then
+ jtag_req <= '0';
+ if request(1 downto 0) = DMI_REQ_RD then
+ request(DBITS + 1 downto 2) <= dmi_din;
+ end if;
+ end if;
+
+ -- Capture state, grab latch content with updated status
+ if capture = '1' then
+ shiftr <= request(ABITS + DBITS + 1 downto 2) & rsp_op;
+ end if;
+
+ end if;
+ end if;
+ end process;
+end architecture behaviour;
+
- fpga/firmware.hex : {copyto : firmware.hex, file_type : user}
file_type : vhdlSource-2008
+ debug_xilinx:
+ files:
+ - dmi_dtm_xilinx.vhdl : {file_type : vhdlSource-2008}
+
+ debug_dummy:
+ files:
+ - dmi_dtm_dummy.vhdl : {file_type : vhdlSource-2008}
+
nexys_a7:
files:
- fpga/nexys_a7.xdc : {file_type : xdc}
targets:
nexys_a7:
default_tool: vivado
- filesets: [core, nexys_a7, soc, fpga]
+ filesets: [core, nexys_a7, soc, fpga, debug_xilinx]
parameters : [memory_size, ram_init_file]
tools:
vivado: {part : xc7a100tcsg324-1}
nexys_video:
default_tool: vivado
- filesets: [core, nexys_video, soc, fpga]
+ filesets: [core, nexys_video, soc, fpga, debug_xilinx]
parameters : [memory_size, ram_init_file]
tools:
vivado: {part : xc7a200tsbg484-1}
arty_a7-35:
default_tool: vivado
- filesets: [core, arty_a7-35, soc, fpga]
+ filesets: [core, arty_a7-35, soc, fpga, debug_xilinx]
parameters : [memory_size, ram_init_file]
tools:
vivado: {part : xc7a35ticsg324-1L}
cmod_a7-35:
default_tool: vivado
- filesets: [core, cmod_a7-35, soc, fpga]
+ filesets: [core, cmod_a7-35, soc, fpga, debug_xilinx]
parameters : [memory_size, ram_init_file, reset_low=false]
tools:
vivado: {part : xc7a35tcpg236-1}
--- /dev/null
+#!/usr/bin/python3
+
+import urjtag;
+
+def do_command(urc, op, addr, data):
+ urc.set_dr_in(op,1,0)
+ urc.set_dr_in(data,65,2)
+ urc.set_dr_in(addr,73,66)
+# print("Sending:", urc.get_dr_in_string())
+ urc.shift_dr()
+ urc.set_dr_in(0x0,73,0)
+ for x in range(5):
+ urc.shift_dr()
+# print("Received:", urc.get_dr_out_string())
+ rsp_code = urc.get_dr_out(1,0)
+ if rsp_code == 0:
+ return urc.get_dr_out(65,2)
+ if rsp_code != 3:
+ print("Weird response ! rsp=%x" % rsp_code);
+ print("Timeout sending command !")
+
+def do_read(urc, addr):
+ return do_command(urc, 1, addr, 0)
+
+def do_write(urc, addr, val):
+ do_command(urc, 2, addr, val)
+
+def main():
+ # Init jtag
+ #urjtag.loglevel( urjtag.URJ_LOG_LEVEL_ALL )
+
+ urc = urjtag.chain()
+ urc.cable("DigilentHS1")
+ print('Cable frequency:', urc.get_frequency())
+ #urc.tap_detect()
+ #length = urc.len()
+ #for i in range(0,urc.len()):
+ # idcode = urc.partid(0)
+ # print('[%d] 0x%08x' % (i, idcode))
+ urc.addpart(6);
+ print("Part ID: ", urc.partid(0))
+ #urc.part(0)
+ #urc.reset();
+ urc.add_register("USER2_REG", 74);
+ urc.add_instruction("USER2", "000011", "USER2_REG");
+ urc.add_register("IDCODE_REG", 32);
+ urc.add_instruction("IDCODE", "001001", "IDCODE_REG");
+ # Send test command
+ urc.set_instruction("IDCODE")
+ urc.shift_ir()
+ urc.shift_dr()
+ print("Got:", hex(urc.get_dr_out()))
+
+ urc.set_instruction("USER2")
+ urc.shift_ir()
+
+ print("Reading 0x00: %x" % do_read(urc, 0))
+ print("Reading 0xaa: %x" % do_read(urc, 0xaa))
+
+
+if __name__ == "__main__":
+ main()
--- /dev/null
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.ALL;
+
+library unisim;
+use unisim.vcomponents.all;
+
+entity BSCANE2 is
+ generic(jtag_chain: INTEGER);
+ port(capture : out std_logic;
+ drck : out std_logic;
+ reset : out std_logic;
+ runtest : out std_logic;
+ sel : out std_logic;
+ shift : out std_logic;
+ tck : out std_logic;
+ tdi : out std_logic;
+ tms : out std_logic;
+ update : out std_logic;
+ tdo : in std_logic
+ );
+end BSCANE2;
+
+architecture behaviour of BSCANE2 is
+ alias j : glob_jtag_t is glob_jtag;
+begin
+ sel <= j.sel(jtag_chain);
+ tck <= j.tck;
+ drck <= tck and sel and (capture or shift);
+ capture <= j.capture;
+ reset <= j.reset;
+ runtest <= j.runtest;
+ shift <= j.shift;
+ tdi <= j.tdi;
+ tms <= j.tms;
+ update <= j.update;
+ j.tdo <= tdo;
+end architecture behaviour;
+
--- /dev/null
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+entity BUFG is
+ port(I : in std_logic;
+ O : out std_logic
+ );
+end BUFG;
+architecture behaviour of BUFG is
+begin
+ O <= I;
+end architecture behaviour;
--- /dev/null
+library IEEE;
+use IEEE.std_logic_1164.all;
+
+package vcomponents is
+
+ -- Global JTAG signals. Xilinx implementation hooks that up to
+ -- their internal JTAG tap, we just expose them for the testbench
+ -- to use. These are used by our BSCANE2 block.
+ --
+ type glob_jtag_t is record
+ reset : std_logic;
+ tck : std_logic;
+ tdo : std_logic;
+ tdi : std_logic;
+ tms : std_logic;
+ sel : std_logic_vector(4 downto 1);
+ capture : std_logic;
+ shift : std_logic;
+ update : std_logic;
+ runtest : std_logic;
+ end record glob_jtag_t;
+ signal glob_jtag : glob_jtag_t;
+
+ component BSCANE2 is
+ generic(jtag_chain: integer);
+ port(capture : out std_logic;
+ drck : out std_logic;
+ reset : out std_logic;
+ runtest : out std_logic;
+ sel : out std_logic;
+ shift : out std_logic;
+ tck : out std_logic;
+ tdi : out std_logic;
+ tms : out std_logic;
+ update : out std_logic;
+ tdo : in std_logic
+ );
+ end component BSCANE2;
+
+ component BUFG is
+ port(I : in std_logic;
+ O : out std_logic
+ );
+ end component BUFG;
+end package vcomponents;
signal wb_bram_out : wishbone_slave_out;
constant mem_adr_bits : positive := positive(ceil(log2(real(MEMORY_SIZE))));
- -- Debug signals (used in SIM only)
+ -- Core debug signals (used in SIM only)
signal registers : regfile;
signal terminate : std_ulogic;
+ -- DMI debug bus signals
+ signal dmi_addr : std_ulogic_vector(7 downto 0);
+ signal dmi_din : std_ulogic_vector(63 downto 0);
+ signal dmi_dout : std_ulogic_vector(63 downto 0);
+ signal dmi_req : std_ulogic;
+ signal dmi_wr : std_ulogic;
+ signal dmi_ack : std_ulogic;
+
begin
-- Processor core
wishbone_out => wb_bram_out
);
+ -- DMI(debug bus) <-> JTAG bridge
+ dtm: entity work.dmi_dtm
+ generic map(
+ ABITS => 8,
+ DBITS => 64
+ )
+ port map(
+ sys_clk => system_clk,
+ sys_reset => rst,
+ dmi_addr => dmi_addr,
+ dmi_din => dmi_din,
+ dmi_dout => dmi_dout,
+ dmi_req => dmi_req,
+ dmi_wr => dmi_wr,
+ dmi_ack => dmi_ack
+ );
+
+ -- Dummy loopback until a debug module is present
+ dmi_din <= dmi_dout;
+ dmi_ack <= dmi_ack;
+
end architecture behaviour;