forked from cores/microwatt
Compare commits
21 Commits
master
...
caravel-20
Author | SHA1 | Date |
---|---|---|
Anton Blanchard | 3da9642020 | 4 years ago |
Anton Blanchard | 6e94b047b8 | 4 years ago |
Anton Blanchard | 7ec66d47fe | 4 years ago |
Jordan Niethe | 901cccd7da | 4 years ago |
Anton Blanchard | 4667af332e | 4 years ago |
Anton Blanchard | a9a8bee920 | 4 years ago |
Anton Blanchard | 84f24a4773 | 4 years ago |
Anton Blanchard | 2e3668f840 | 4 years ago |
Michael Neuling | c87b883a82 | 4 years ago |
Michael Neuling | b3a52bf931 | 4 years ago |
Anton Blanchard | 9747879643 | 4 years ago |
Anton Blanchard | 26fa3eda69 | 4 years ago |
Anton Blanchard | 03e213a393 | 4 years ago |
Anton Blanchard | 6bc8b3e7ad | 4 years ago |
Anton Blanchard | 776e3b4815 | 4 years ago |
Anton Blanchard | e8e3e9bd17 | 4 years ago |
Anton Blanchard | ef2ee09d1f | 4 years ago |
Michael Neuling | 104e8b8b2a | 4 years ago |
Anton Blanchard | ffcd9c6989 | 4 years ago |
Anton Blanchard | 47dae4e9d4 | 4 years ago |
Anton Blanchard | 6544dbe94c | 4 years ago |
@ -0,0 +1,70 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
import re
|
||||
|
||||
module_regex = r'[a-zA-Z0-9_\.\\]+'
|
||||
|
||||
# match:
|
||||
# module dcache(clk, rst, d_in, m_in, wishbone_in, d_out, m_out, stall_out, wishbone_out);
|
||||
module_re = re.compile(r'module\s+(' + module_regex + r')\((.*)\);')
|
||||
|
||||
# match:
|
||||
# dcache_64_2_2_2_2_12_0 dcache_0 (
|
||||
hookup_re = re.compile(r'\s+(' + module_regex + r') ' + module_regex + r'\s+\(')
|
||||
|
||||
header1 = """\
|
||||
`ifdef USE_POWER_PINS
|
||||
vdda1, vdda2, vssa1, vssa2, vccd1, vccd2, vssd1, vssd2,
|
||||
`endif\
|
||||
"""
|
||||
|
||||
header2 = """\
|
||||
`ifdef USE_POWER_PINS
|
||||
inout vdda1; // User area 1 3.3V supply
|
||||
inout vdda2; // User area 2 3.3V supply
|
||||
inout vssa1; // User area 1 analog ground
|
||||
inout vssa2; // User area 2 analog ground
|
||||
inout vccd1; // User area 1 1.8V supply
|
||||
inout vccd2; // User area 2 1.8v supply
|
||||
inout vssd1; // User area 1 digital ground
|
||||
inout vssd2; // User area 2 digital ground
|
||||
`endif\
|
||||
"""
|
||||
|
||||
header3 = """\
|
||||
`ifdef USE_POWER_PINS
|
||||
.vdda1(vdda1), // User area 1 3.3V power
|
||||
.vdda2(vdda2), // User area 2 3.3V power
|
||||
.vssa1(vssa1), // User area 1 analog ground
|
||||
.vssa2(vssa2), // User area 2 analog ground
|
||||
.vccd1(vccd1), // User area 1 1.8V power
|
||||
.vccd2(vccd2), // User area 2 1.8V power
|
||||
.vssd1(vssd1), // User area 1 digital ground
|
||||
.vssd2(vssd2), // User area 2 digital ground
|
||||
`endif\
|
||||
"""
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
print("Usage: insert_power.py verilog.v module1 module2..")
|
||||
sys.exit(1);
|
||||
|
||||
verilog_file = sys.argv[1]
|
||||
modules = sys.argv[2:]
|
||||
|
||||
with open(sys.argv[1]) as f:
|
||||
for line in f:
|
||||
m = module_re.match(line)
|
||||
m2 = hookup_re.match(line)
|
||||
if m and m.group(1) in modules:
|
||||
module_name = m.group(1)
|
||||
module_args = m.group(2)
|
||||
print('module %s(' % module_name)
|
||||
print(header1)
|
||||
print(' %s);' % module_args)
|
||||
print(header2)
|
||||
elif m2 and m2.group(1) in modules:
|
||||
print(line, end='')
|
||||
print(header3)
|
||||
else:
|
||||
print(line, end='')
|
@ -0,0 +1,54 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
# process microwatt verilog
|
||||
|
||||
FILE=microwatt.v
|
||||
|
||||
# Remove these modules that are implemented as hard macros
|
||||
for module in register_file_0_1489f923c4dca729178b3e3233458550d8dddf29 dcache_64_2_2_2_2_12_0 icache_64_8_2_2_4_12_56_0_5ba93c9db0cff93f52b521d7420e43f6eda2784f cache_ram_4_64_1489f923c4dca729178b3e3233458550d8dddf29 cache_ram_4_64_3f29546453678b855931c174a97d6c0894b8f546 plru_1 multiply_4
|
||||
do
|
||||
sed -i "/^module $module/,/^endmodule/d" $FILE
|
||||
done
|
||||
|
||||
# Remove the debug bus in the places we call our macros
|
||||
for module in dcache_64_2_2_2_2_12_0 icache_64_8_2_2_4_12_56_0_5ba93c9db0cff93f52b521d7420e43f6eda2784f register_file_0_1489f923c4dca729178b3e3233458550d8dddf29; do
|
||||
for port in dbg_gpr log_out sim_dump; do
|
||||
sed -i "/ $module /,/);/{ /$port/d }" $FILE
|
||||
done
|
||||
done
|
||||
|
||||
# Rename these modules to match the hard macro names
|
||||
sed -i 's/register_file_0_1489f923c4dca729178b3e3233458550d8dddf29/register_file/' $FILE
|
||||
sed -i 's/dcache_64_2_2_2_2_12_0/dcache/' $FILE
|
||||
sed -i 's/icache_64_8_2_2_4_12_56_0_5ba93c9db0cff93f52b521d7420e43f6eda2784f/icache/' $FILE
|
||||
sed -i 's/toplevel/microwatt/' $FILE
|
||||
|
||||
# Add power to all macros, and route power in microwatt down to them
|
||||
caravel/insert_power.py $FILE dcache icache register_file multiply_4 RAM_512x64 main_bram_64_10_4096_a75adb9e07879fb6c63b494abe06e3f9a6bb2ed9 soc_4096_50000000_0_0_4_0_4_0_c832069ef22b63469d396707bc38511cc2410ddb wishbone_bram_wrapper_4096_a75adb9e07879fb6c63b494abe06e3f9a6bb2ed9 microwatt core_0_602f7ae323a872754ff5ac989c2e00f60e206d8e execute1_0_0e356ba505631fbf715758bed27d503f8b260e3a > $FILE.tmp && mv $FILE.tmp $FILE
|
||||
|
||||
# Add defines
|
||||
sed -i '1 a\
|
||||
\
|
||||
/* Hard macros */\
|
||||
`ifdef SIM\
|
||||
`include "RAM_512x64.v"\
|
||||
`include "register_file.v"\
|
||||
`include "icache.v"\
|
||||
`include "dcache.v"\
|
||||
`include "multiply_4.v"\
|
||||
`endif\
|
||||
\
|
||||
/* JTAG */\
|
||||
`include "tap_top.v"\
|
||||
\
|
||||
/* UART */\
|
||||
`include "raminfr.v"\
|
||||
`include "uart_receiver.v"\
|
||||
`include "uart_rfifo.v"\
|
||||
`include "uart_tfifo.v"\
|
||||
`include "uart_transmitter.v"\
|
||||
`include "uart_defines.v"\
|
||||
`include "uart_regs.v"\
|
||||
`include "uart_sync_flops.v"\
|
||||
`include "uart_wb.v"\
|
||||
`include "uart_top.v"' $FILE
|
@ -0,0 +1,28 @@
|
||||
module RAM_512x64 (
|
||||
input CLK,
|
||||
input [7:0] WE,
|
||||
input EN,
|
||||
input [63:0] Di,
|
||||
output [63:0] Do,
|
||||
input [8:0] A
|
||||
);
|
||||
|
||||
DFFRAM #(.COLS(2), .filename("even.hex")) LBANK (
|
||||
.CLK(CLK),
|
||||
.WE(WE[3:0]),
|
||||
.EN(EN),
|
||||
.Di(Di[31:0]),
|
||||
.Do(Do[31:0]),
|
||||
.A(A[8:0])
|
||||
);
|
||||
|
||||
DFFRAM #(.COLS(2), .filename("odd.hex")) HBANK (
|
||||
.CLK(CLK),
|
||||
.WE(WE[7:4]),
|
||||
.EN(EN),
|
||||
.Di(Di[63:32]),
|
||||
.Do(Do[63:32]),
|
||||
.A(A[8:0])
|
||||
);
|
||||
|
||||
endmodule
|
@ -0,0 +1,302 @@
|
||||
-- JTAG to DMI interface, based on the Xilinx version
|
||||
--
|
||||
-- DMI bus
|
||||
--
|
||||
-- req : ____/------------\_____
|
||||
-- addr: xxxx< >xxxxx, based on the Xilinx version
|
||||
-- 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_trst 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;
|
||||
|
||||
entity dmi_dtm_jtag 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
|
||||
jtag_tck : in std_ulogic;
|
||||
jtag_tdi : in std_ulogic;
|
||||
jtag_tms : in std_ulogic;
|
||||
jtag_trst : in std_ulogic;
|
||||
jtag_tdo : out std_ulogic
|
||||
);
|
||||
end entity dmi_dtm_jtag;
|
||||
|
||||
architecture behaviour of dmi_dtm_jtag is
|
||||
|
||||
-- Signals coming out of the JTAG TAP controller
|
||||
signal capture : std_ulogic;
|
||||
signal update : std_ulogic;
|
||||
signal sel : std_ulogic;
|
||||
signal shift : std_ulogic;
|
||||
signal tdi : std_ulogic;
|
||||
signal tdo : 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_tck)
|
||||
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";
|
||||
|
||||
attribute ASYNC_REG : string;
|
||||
attribute ASYNC_REG of jtag_req_0: signal is "TRUE";
|
||||
attribute ASYNC_REG of jtag_req_1: signal is "TRUE";
|
||||
attribute ASYNC_REG of dmi_ack_0: signal is "TRUE";
|
||||
attribute ASYNC_REG of dmi_ack_1: signal is "TRUE";
|
||||
|
||||
component tap_top port (
|
||||
-- JTAG pads
|
||||
tms_pad_i : in std_ulogic;
|
||||
tck_pad_i : in std_ulogic;
|
||||
trst_pad_i : in std_ulogic;
|
||||
tdi_pad_i : in std_ulogic;
|
||||
tdo_pad_o : out std_ulogic;
|
||||
tdo_padoe_o : out std_ulogic;
|
||||
|
||||
-- TAP states
|
||||
shift_dr_o : out std_ulogic;
|
||||
pause_dr_o : out std_ulogic;
|
||||
update_dr_o : out std_ulogic;
|
||||
capture_dr_o : out std_ulogic;
|
||||
|
||||
-- Select signals for boundary scan or mbist
|
||||
extest_select_o : out std_ulogic;
|
||||
sample_preload_select_o : out std_ulogic;
|
||||
mbist_select_o : out std_ulogic;
|
||||
debug_select_o : out std_ulogic;
|
||||
|
||||
-- TDO signal that is connected to TDI of sub-modules.
|
||||
tdo_o : out std_ulogic;
|
||||
|
||||
-- TDI signals from sub-modules
|
||||
debug_tdi_i : in std_ulogic;
|
||||
bs_chain_tdi_i : in std_ulogic;
|
||||
mbist_tdi_i : in std_ulogic
|
||||
);
|
||||
end component;
|
||||
|
||||
begin
|
||||
tap_top0 : tap_top
|
||||
port map (
|
||||
tms_pad_i => jtag_tms,
|
||||
tck_pad_i => jtag_tck,
|
||||
trst_pad_i => jtag_trst,
|
||||
tdi_pad_i => jtag_tdi,
|
||||
tdo_pad_o => jtag_tdo,
|
||||
tdo_padoe_o => open, -- what to do with this?
|
||||
|
||||
shift_dr_o => shift,
|
||||
pause_dr_o => open, -- what to do with this?
|
||||
update_dr_o => update,
|
||||
capture_dr_o => capture,
|
||||
|
||||
-- connect boundary scan and mbist?
|
||||
extest_select_o => open,
|
||||
sample_preload_select_o => open,
|
||||
mbist_select_o => open,
|
||||
debug_select_o => sel,
|
||||
|
||||
tdo_o => tdi,
|
||||
debug_tdi_i => tdo,
|
||||
bs_chain_tdi_i => '0',
|
||||
mbist_tdi_i => '0'
|
||||
);
|
||||
|
||||
-- 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_tck, jtag_trst)
|
||||
begin
|
||||
-- jtag_trst is async (see comments)
|
||||
if jtag_trst = '1' then
|
||||
dmi_ack_0 <= '0';
|
||||
dmi_ack_1 <= '0';
|
||||
elsif rising_edge(jtag_tck) 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_tck, jtag_trst, sys_reset)
|
||||
begin
|
||||
if jtag_trst = '1' or sys_reset = '1' then
|
||||
shiftr <= (others => '0');
|
||||
jtag_req <= '0';
|
||||
request <= (others => '0');
|
||||
elsif rising_edge(jtag_tck) 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;
|
@ -0,0 +1,337 @@
|
||||
4800012c
|
||||
00000000
|
||||
08000048
|
||||
a600607d
|
||||
05009f42
|
||||
14004a39
|
||||
a64b7b7d
|
||||
480000f4
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
08000048
|
||||
a600607d
|
||||
05009f42
|
||||
14004a39
|
||||
a64b7b7d
|
||||
48000004
|
||||
60210000
|
||||
64210000
|
||||
3d800000
|
||||
798c07c6
|
||||
618c0414
|
||||
4e800421
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
ebc1fff0
|
||||
ebe1fff8
|
||||
4e800020
|
||||
38428a00
|
||||
fbe1fff8
|
||||
f821ffd1
|
||||
60000000
|
||||
38628000
|
||||
60000000
|
||||
60000000
|
||||
5463063e
|
||||
480000b9
|
||||
2c1f000d
|
||||
3860000a
|
||||
60000000
|
||||
00000000
|
||||
00000180
|
||||
38428a00
|
||||
89228090
|
||||
39428088
|
||||
41820030
|
||||
39290014
|
||||
7d204eaa
|
||||
4182ffec
|
||||
7c0004ac
|
||||
5463063e
|
||||
e92a0000
|
||||
7c0004ac
|
||||
71290001
|
||||
e86a0000
|
||||
7c0004ac
|
||||
4bffffd0
|
||||
00000000
|
||||
3c400001
|
||||
60000000
|
||||
60000000
|
||||
2c090000
|
||||
e92a0000
|
||||
7c0004ac
|
||||
71290020
|
||||
e92a0000
|
||||
7c604faa
|
||||
e92a0000
|
||||
7c0004ac
|
||||
71290008
|
||||
5469063e
|
||||
7c0004ac
|
||||
4e800020
|
||||
00000000
|
||||
3c400001
|
||||
7c0802a6
|
||||
fbc1fff0
|
||||
f8010010
|
||||
8fdf0001
|
||||
40820010
|
||||
38600000
|
||||
281e000a
|
||||
3860000d
|
||||
7fc3f378
|
||||
4bffffd0
|
||||
01000000
|
||||
7c691b78
|
||||
7d4918ae
|
||||
4d820020
|
||||
4bfffff0
|
||||
00000000
|
||||
3c400001
|
||||
3d40c000
|
||||
794a0020
|
||||
7d4056ea
|
||||
794a0600
|
||||
79290020
|
||||
7d204eea
|
||||
41820018
|
||||
61290040
|
||||
7c0004ac
|
||||
7929f804
|
||||
79290fc3
|
||||
79080020
|
||||
f9028088
|
||||
61082000
|
||||
41820084
|
||||
39200001
|
||||
3d00c000
|
||||
3920ff80
|
||||
7c0004ac
|
||||
e9228088
|
||||
7d404faa
|
||||
794ac202
|
||||
7c0004ac
|
||||
e9228088
|
||||
3929000c
|
||||
7d404faa
|
||||
39290010
|
||||
7d404faa
|
||||
39400007
|
||||
7c0004ac
|
||||
4e800020
|
||||
394affff
|
||||
3d20c000
|
||||
79290020
|
||||
7d404fea
|
||||
00000000
|
||||
00000000
|
||||
38428a00
|
||||
89228090
|
||||
2f890000
|
||||
e9228088
|
||||
41820024
|
||||
2c230000
|
||||
614a0001
|
||||
7c0004ac
|
||||
4e800020
|
||||
4bffffe0
|
||||
60630002
|
||||
7c0004ac
|
||||
4e800020
|
||||
00000000
|
||||
00000010
|
||||
00527a01
|
||||
00010c1b
|
||||
00000018
|
||||
00000070
|
||||
9f7e4111
|
||||
00000010
|
||||
00527a01
|
||||
00010c1b
|
||||
00000018
|
||||
00000084
|
||||
00000010
|
||||
fffffcf8
|
||||
00000000
|
||||
00000040
|
||||
00000060
|
||||
9e019f00
|
||||
447e4111
|
||||
4106dedf
|
||||
00000010
|
||||
fffffd98
|
||||
00000000
|
||||
00000080
|
||||
0000012c
|
||||
00000010
|
||||
fffffec4
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
2020200a
|
||||
20202e6f
|
||||
20222e20
|
||||
202e2220
|
||||
776d2e20
|
||||
4d202020
|
||||
74746177
|
||||
726f7720
|
||||
202e2020
|
||||
20202e20
|
||||
205c2020
|
||||
20202020
|
||||
2e2e3b20
|
||||
0a202020
|
||||
3b2e2e3b
|
||||
200a2020
|
||||
20277777
|
@ -0,0 +1,63 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library work;
|
||||
|
||||
entity main_bram is
|
||||
generic(
|
||||
WIDTH : natural := 64;
|
||||
HEIGHT_BITS : natural := 11;
|
||||
MEMORY_SIZE : natural := (8*1024);
|
||||
RAM_INIT_FILE : string
|
||||
);
|
||||
port(
|
||||
clk : in std_logic;
|
||||
addr : in std_logic_vector(HEIGHT_BITS - 1 downto 0) ;
|
||||
di : in std_logic_vector(WIDTH-1 downto 0);
|
||||
do : out std_logic_vector(WIDTH-1 downto 0);
|
||||
sel : in std_logic_vector((WIDTH/8)-1 downto 0);
|
||||
re : in std_ulogic;
|
||||
we : in std_ulogic
|
||||
);
|
||||
end entity main_bram;
|
||||
|
||||
architecture behaviour of main_bram is
|
||||
component RAM_512x64 port (
|
||||
CLK : in std_ulogic;
|
||||
WE : in std_ulogic_vector(7 downto 0);
|
||||
EN : in std_ulogic;
|
||||
Di : in std_ulogic_vector(63 downto 0);
|
||||
Do : out std_ulogic_vector(63 downto 0);
|
||||
A : in std_ulogic_vector(8 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
signal sel_qual: std_ulogic_vector((WIDTH/8)-1 downto 0);
|
||||
|
||||
signal obuf : std_logic_vector(WIDTH-1 downto 0);
|
||||
begin
|
||||
assert WIDTH = 64;
|
||||
-- Do we have a log2 round up issue here?
|
||||
assert HEIGHT_BITS = 10;
|
||||
assert MEMORY_SIZE = (4*1024);
|
||||
|
||||
sel_qual <= sel when we = '1' else (others => '0');
|
||||
|
||||
memory_0 : RAM_512x64
|
||||
port map (
|
||||
CLK => clk,
|
||||
WE => sel_qual(7 downto 0),
|
||||
EN => re or we,
|
||||
Di => di(63 downto 0),
|
||||
Do => obuf(63 downto 0),
|
||||
A => addr(8 downto 0)
|
||||
);
|
||||
|
||||
-- The wishbone BRAM wrapper assumes a 1 cycle delay
|
||||
memory_read_buffer: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
do <= obuf;
|
||||
end if;
|
||||
end process;
|
||||
end architecture behaviour;
|
@ -0,0 +1,232 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.wishbone_types.all;
|
||||
|
||||
entity toplevel is
|
||||
generic (
|
||||
MEMORY_SIZE : integer := 8192;
|
||||
RAM_INIT_FILE : string := "firmware.hex";
|
||||
RESET_LOW : boolean := true;
|
||||
CLK_INPUT : positive := 100000000;
|
||||
CLK_FREQUENCY : positive := 100000000;
|
||||
HAS_FPU : boolean := false;
|
||||
NO_BRAM : boolean := false;
|
||||
DISABLE_FLATTEN_CORE : boolean := false;
|
||||
SPI_FLASH_OFFSET : integer := 0;
|
||||
SPI_FLASH_DEF_CKDV : natural := 4;
|
||||
SPI_FLASH_DEF_QUAD : boolean := false;
|
||||
LOG_LENGTH : natural := 0;
|
||||
UART_IS_16550 : boolean := true;
|
||||
HAS_UART1 : boolean := false;
|
||||
HAS_JTAG : boolean := true;
|
||||
INPUT_IOS : integer range 0 to 32 := 32;
|
||||
OUTPUT_IOS : integer range 0 to 32 := 32
|
||||
);
|
||||
port(
|
||||
ext_clk : in std_ulogic;
|
||||
ext_rst : in std_ulogic;
|
||||
|
||||
-- UART0 signals:
|
||||
uart0_txd : out std_ulogic;
|
||||
uart0_rxd : in std_ulogic;
|
||||
|
||||
-- UART1 signals:
|
||||
uart1_txd : out std_ulogic;
|
||||
uart1_rxd : in std_ulogic;
|
||||
|
||||
-- SPI
|
||||
spi_flash_cs_n : out std_ulogic;
|
||||
spi_flash_clk : out std_ulogic;
|
||||
spi_flash_sdat_i : in std_ulogic_vector(3 downto 0);
|
||||
spi_flash_sdat_o : out std_ulogic_vector(3 downto 0);
|
||||
spi_flash_sdat_oe : out std_ulogic_vector(3 downto 0);
|
||||
|
||||
-- JTAG signals:
|
||||
jtag_tck : in std_ulogic;
|
||||
jtag_tdi : in std_ulogic;
|
||||
jtag_tms : in std_ulogic;
|
||||
jtag_trst : in std_ulogic;
|
||||
jtag_tdo : out std_ulogic;
|
||||
|
||||
-- Bill's bus
|
||||
oib_clk : out std_ulogic;
|
||||
ob_data : out std_ulogic_vector(7 downto 0);
|
||||
ob_pty : out std_ulogic;
|
||||
|
||||
ib_data : in std_ulogic_vector(7 downto 0);
|
||||
ib_pty : in std_ulogic;
|
||||
|
||||
-- IO Signals
|
||||
gpio_out : out std_ulogic_vector(OUTPUT_IOS-1 downto 0);
|
||||
gpio_in : in std_ulogic_vector(INPUT_IOS-1 downto 0);
|
||||
|
||||
-- Add an I/O pin to select fetching from flash on reset
|
||||
alt_reset : in std_ulogic
|
||||
);
|
||||
end entity toplevel;
|
||||
|
||||
architecture behaviour of toplevel is
|
||||
-- reset signals
|
||||
signal system_rst : std_ulogic;
|
||||
|
||||
-- external bus wishbone connection
|
||||
signal wb_dram_out : wishbone_master_out;
|
||||
signal wb_dram_in : wishbone_slave_out;
|
||||
|
||||
-- external bus
|
||||
signal wb_mc_adr : wishbone_addr_type;
|
||||
signal wb_mc_dat_o : wishbone_data_type;
|
||||
signal wb_mc_cyc : std_ulogic;
|
||||
signal wb_mc_stb : std_ulogic;
|
||||
signal wb_mc_sel : wishbone_sel_type;
|
||||
signal wb_mc_we : std_ulogic;
|
||||
signal wb_mc_dat_i : wishbone_data_type;
|
||||
signal wb_mc_ack : std_ulogic;
|
||||
signal wb_mc_stall : std_ulogic;
|
||||
|
||||
signal wb_logic_analyzer_out : wb_io_slave_out := wb_io_slave_out_init;
|
||||
signal wb_logic_analyzer_in : wb_io_master_out;
|
||||
|
||||
signal wb_ext_io_in : wb_io_master_out;
|
||||
signal wb_ext_io_out : wb_io_slave_out;
|
||||
signal wb_ext_is_eth : std_ulogic;
|
||||
|
||||
begin
|
||||
|
||||
system_rst <= not ext_rst when RESET_LOW else ext_rst;
|
||||
|
||||
-- Main SoC
|
||||
soc0: entity work.soc
|
||||
generic map(
|
||||
MEMORY_SIZE => MEMORY_SIZE,
|
||||
RAM_INIT_FILE => RAM_INIT_FILE,
|
||||
SIM => false,
|
||||
CLK_FREQ => CLK_FREQUENCY,
|
||||
HAS_FPU => HAS_FPU,
|
||||
HAS_DRAM => true,
|
||||
DRAM_SIZE => 0,
|
||||
DRAM_INIT_SIZE => 0,
|
||||
DISABLE_FLATTEN_CORE => DISABLE_FLATTEN_CORE,
|
||||
HAS_SPI_FLASH => true,
|
||||
SPI_FLASH_DLINES => 4,
|
||||
SPI_FLASH_OFFSET => SPI_FLASH_OFFSET,
|
||||
SPI_FLASH_DEF_CKDV => SPI_FLASH_DEF_CKDV,
|
||||
SPI_FLASH_DEF_QUAD => SPI_FLASH_DEF_QUAD,
|
||||
LOG_LENGTH => LOG_LENGTH,
|
||||
UART0_IS_16550 => UART_IS_16550,
|
||||
HAS_UART1 => HAS_UART1,
|
||||
HAS_JTAG => HAS_JTAG,
|
||||
HAS_LITEETH => true
|
||||
)
|
||||
port map (
|
||||
-- System signals
|
||||
system_clk => ext_clk,
|
||||
rst => system_rst,
|
||||
|
||||
-- UART signals
|
||||
uart0_txd => uart0_txd,
|
||||
uart0_rxd => uart0_rxd,
|
||||
|
||||
-- UART1 signals
|
||||
uart1_txd => uart1_txd,
|
||||
uart1_rxd => uart1_rxd,
|
||||
|
||||
-- SPI signals
|
||||
spi_flash_sck => spi_flash_clk,
|
||||
spi_flash_cs_n => spi_flash_cs_n,
|
||||
spi_flash_sdat_o => spi_flash_sdat_o,
|
||||
spi_flash_sdat_oe => spi_flash_sdat_oe,
|
||||
spi_flash_sdat_i => spi_flash_sdat_i,
|
||||
|
||||
-- JTAG signals
|
||||
jtag_tck => jtag_tck,
|
||||
jtag_tdi => jtag_tdi,
|
||||
jtag_tms => jtag_tms,
|
||||
jtag_trst => jtag_trst,
|
||||
jtag_tdo => jtag_tdo,
|
||||
|
||||
-- Use DRAM wishbone for Bill's bus
|
||||
wb_dram_in => wb_dram_out,
|
||||
wb_dram_out => wb_dram_in,
|
||||
|
||||
wb_ext_io_in => wb_ext_io_in,
|
||||
wb_ext_io_out => wb_ext_io_out,
|
||||
wb_ext_is_eth => wb_ext_is_eth,
|
||||
|
||||
-- Reset PC to flash offset 0 (ie 0xf000000)
|
||||
alt_reset => alt_reset
|
||||
);
|
||||
|
||||
mc0: entity work.mc
|
||||
generic map(
|
||||
WB_AW => 32, -- wishbone_addr_bits
|
||||
WB_DW => 64, -- wishbone_data_bits
|
||||
OIB_DW => 8,
|
||||
OIB_RATIO => 2, -- bill said this
|
||||
BAR_INIT => x"1fff" -- dram has 512 bit space. CPU gives
|
||||
-- top 3 bits as 0. carve off small
|
||||
-- chunk at top for config space.
|
||||
)
|
||||
port map (
|
||||
clk => ext_clk,
|
||||
rst => system_rst,
|
||||
|
||||
wb_cyc => wb_mc_cyc,
|
||||
wb_stb => wb_mc_stb,
|
||||
wb_we => wb_mc_we,
|
||||
wb_addr => wb_mc_adr,
|
||||
wb_wr_data => wb_mc_dat_o,
|
||||
wb_sel => wb_mc_sel,
|
||||
wb_ack => wb_mc_ack,
|
||||
-- wb_err => wb_mc_err, ??
|
||||
wb_stall => wb_mc_stall,
|
||||
wb_rd_data => wb_mc_dat_i,
|
||||
oib_clk => oib_clk,
|
||||
ob_data => ob_data,
|
||||
ob_pty => ob_pty,
|
||||
ib_data => ib_data,
|
||||
ib_pty => ib_pty
|
||||
-- err => ob _err,
|
||||
-- int => ob int
|
||||
);
|
||||
|
||||
logic_analyzer: entity work.logic_analyzer
|
||||
generic map(
|
||||
INPUT_IOS => INPUT_IOS,
|
||||
OUTPUT_IOS => OUTPUT_IOS
|
||||
)
|
||||
port map(
|
||||
clk => ext_clk,
|
||||
rst => system_rst,
|
||||
wb_in => wb_logic_analyzer_in,
|
||||
wb_out => wb_logic_analyzer_out,
|
||||
io_in => gpio_in,
|
||||
io_out => gpio_out
|
||||
);
|
||||
|
||||
wb_logic_analyzer_in.adr <= wb_ext_io_in.adr;
|
||||
wb_logic_analyzer_in.dat <= wb_ext_io_in.dat;
|
||||
wb_logic_analyzer_in.cyc <= wb_ext_io_in.cyc and wb_ext_is_eth;
|
||||
wb_logic_analyzer_in.stb <= wb_ext_io_in.stb;
|
||||
wb_logic_analyzer_in.sel <= wb_ext_io_in.sel;
|
||||
wb_logic_analyzer_in.we <= wb_ext_io_in.we;
|
||||
|
||||
wb_ext_io_out <= wb_logic_analyzer_out;
|
||||
|
||||
|
||||
-- External bus wishbone
|
||||
wb_mc_adr <= wb_dram_out.adr;
|
||||
wb_mc_dat_o <= wb_dram_out.dat;
|
||||
wb_mc_cyc <= wb_dram_out.cyc;
|
||||
wb_mc_stb <= wb_dram_out.stb;
|
||||
wb_mc_sel <= wb_dram_out.sel;
|
||||
wb_mc_we <= wb_dram_out.we;
|
||||
|
||||
wb_dram_in.dat <= wb_mc_dat_i;
|
||||
wb_dram_in.ack <= wb_mc_ack;
|
||||
wb_dram_in.stall <= wb_mc_stall;
|
||||
|
||||
end architecture behaviour;
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,636 @@
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// tap_top.v ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// This file is part of the JTAG Test Access Port (TAP) ////
|
||||
//// http://www.opencores.org/projects/jtag/ ////
|
||||
//// ////
|
||||
//// Author(s): ////
|
||||
//// Igor Mohor (igorm@opencores.org) ////
|
||||
//// ////
|
||||
//// ////
|
||||
//// All additional information is avaliable in the README.txt ////
|
||||
//// file. ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//// ////
|
||||
//// Copyright (C) 2000 - 2003 Authors ////
|
||||
//// ////
|
||||
//// This source file may be used and distributed without ////
|
||||
//// restriction provided that this copyright statement is not ////
|
||||
//// removed from the file and that any derivative work contains ////
|
||||
//// the original copyright notice and the associated disclaimer. ////
|
||||
//// ////
|
||||
//// This source file is free software; you can redistribute it ////
|
||||
//// and/or modify it under the terms of the GNU Lesser General ////
|
||||
//// Public License as published by the Free Software Foundation; ////
|
||||
//// either version 2.1 of the License, or (at your option) any ////
|
||||
//// later version. ////
|
||||
//// ////
|
||||
//// This source is distributed in the hope that it will be ////
|
||||
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
||||
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
||||
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
||||
//// details. ////
|
||||
//// ////
|
||||
//// You should have received a copy of the GNU Lesser General ////
|
||||
//// Public License along with this source; if not, download it ////
|
||||
//// from http://www.opencores.org/lgpl.shtml ////
|
||||
//// ////
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CVS Revision History
|
||||
//
|
||||
// $Log: not supported by cvs2svn $
|
||||
// Revision 1.5 2004/01/18 09:27:39 simons
|
||||
// Blocking non blocking assignmenst fixed.
|
||||
//
|
||||
// Revision 1.4 2004/01/17 17:37:44 mohor
|
||||
// capture_dr_o added to ports.
|
||||
//
|
||||
// Revision 1.3 2004/01/14 13:50:56 mohor
|
||||
// 5 consecutive TMS=1 causes reset of TAP.
|
||||
//
|
||||
// Revision 1.2 2004/01/08 10:29:44 mohor
|
||||
// Control signals for tdo_pad_o mux are changed to negedge.
|
||||
//
|
||||
// Revision 1.1 2003/12/23 14:52:14 mohor
|
||||
// Directory structure changed. New version of TAP.
|
||||
//
|
||||
// Revision 1.10 2003/10/23 18:08:01 mohor
|
||||
// MBIST chain connection fixed.
|
||||
//
|
||||
// Revision 1.9 2003/10/23 16:17:02 mohor
|
||||
// CRC logic changed.
|
||||
//
|
||||
// Revision 1.8 2003/10/21 09:48:31 simons
|
||||
// Mbist support added.
|
||||
//
|
||||
// Revision 1.7 2002/11/06 14:30:10 mohor
|
||||
// Trst active high. Inverted on higher layer.
|
||||
//
|
||||
// Revision 1.6 2002/04/22 12:55:56 mohor
|
||||
// tdo_padoen_o changed to tdo_padoe_o. Signal is active high.
|
||||
//
|
||||
// Revision 1.5 2002/03/26 14:23:38 mohor
|
||||
// Signal tdo_padoe_o changed back to tdo_padoen_o.
|
||||
//
|
||||
// Revision 1.4 2002/03/25 13:16:15 mohor
|
||||
// tdo_padoen_o changed to tdo_padoe_o. Signal was always active high, just
|
||||
// not named correctly.
|
||||
//
|
||||
// Revision 1.3 2002/03/12 14:30:05 mohor
|
||||
// Few outputs for boundary scan chain added.
|
||||
//
|
||||
// Revision 1.2 2002/03/12 10:31:53 mohor
|
||||
// tap_top and dbg_top modules are put into two separate modules. tap_top
|
||||
// contains only tap state machine and related logic. dbg_top contains all
|
||||
// logic necessery for debugging.
|
||||
//
|
||||
// Revision 1.1 2002/03/08 15:28:16 mohor
|
||||
// Structure changed. Hooks for jtag chain added.
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
// Top module
|
||||
module tap_top #(parameter
|
||||
IDCODE_VALUE = 32'h14d57049,
|
||||
IR_LENGTH = 6)
|
||||
(
|
||||
// JTAG pads
|
||||
tms_pad_i,
|
||||
tck_pad_i,
|
||||
trst_pad_i,
|
||||
tdi_pad_i,
|
||||
tdo_pad_o,
|
||||
tdo_padoe_o,
|
||||
|
||||
// TAP states
|
||||
shift_dr_o,
|
||||
pause_dr_o,
|
||||
update_dr_o,
|
||||
capture_dr_o,
|
||||
|
||||
// Select signals for boundary scan or mbist
|
||||
extest_select_o,
|
||||
sample_preload_select_o,
|
||||
mbist_select_o,
|
||||
debug_select_o,
|
||||
|
||||
// TDO signal that is connected to TDI of sub-modules.
|
||||
tdo_o,
|
||||
|
||||
// TDI signals from sub-modules
|
||||
debug_tdi_i, // from debug module
|
||||
bs_chain_tdi_i, // from Boundary Scan Chain
|
||||
mbist_tdi_i // from Mbist Chain
|
||||
);
|
||||
|
||||
|
||||
// JTAG pins
|
||||
input tms_pad_i; // JTAG test mode select pad
|
||||
input tck_pad_i; // JTAG test clock pad
|
||||
input trst_pad_i; // JTAG test reset pad
|
||||
input tdi_pad_i; // JTAG test data input pad
|
||||
output tdo_pad_o; // JTAG test data output pad
|
||||
output tdo_padoe_o; // Output enable for JTAG test data output pad
|
||||
|
||||
// TAP states
|
||||
output shift_dr_o;
|
||||
output pause_dr_o;
|
||||
output update_dr_o;
|
||||
output capture_dr_o;
|
||||
|
||||
// Select signals for boundary scan or mbist
|
||||
output extest_select_o;
|
||||
output sample_preload_select_o;
|
||||
output mbist_select_o;
|
||||
output debug_select_o;
|
||||
|
||||
// TDO signal that is connected to TDI of sub-modules.
|
||||
output tdo_o;
|
||||
|
||||
// TDI signals from sub-modules
|
||||
input debug_tdi_i; // from debug module
|
||||
input bs_chain_tdi_i; // from Boundary Scan Chain
|
||||
input mbist_tdi_i; // from Mbist Chain
|
||||
|
||||
//Internal constants
|
||||
localparam EXTEST = 6'b000000;
|
||||
localparam SAMPLE_PRELOAD = 6'b000001;
|
||||
localparam IDCODE = 6'b001001;
|
||||
localparam DEBUG = 6'b000011;
|
||||
localparam MBIST = 6'b001010;
|
||||
localparam BYPASS = 6'b111111;
|
||||
|
||||
// Registers
|
||||
reg test_logic_reset;
|
||||
reg run_test_idle;
|
||||
reg select_dr_scan;
|
||||
reg capture_dr;
|
||||
reg shift_dr;
|
||||
reg exit1_dr;
|
||||
reg pause_dr;
|
||||
reg exit2_dr;
|
||||
reg update_dr;
|
||||
reg select_ir_scan;
|
||||
reg capture_ir;
|
||||
reg shift_ir, shift_ir_neg;
|
||||
reg exit1_ir;
|
||||
reg pause_ir;
|
||||
reg exit2_ir;
|
||||
reg update_ir;
|
||||
reg extest_select;
|
||||
reg sample_preload_select;
|
||||
reg idcode_select;
|
||||
reg mbist_select;
|
||||
reg debug_select;
|
||||
reg bypass_select;
|
||||
reg tdo_pad_o;
|
||||
reg tdo_padoe_o;
|
||||
reg tms_q1, tms_q2, tms_q3, tms_q4;
|
||||
wire tms_reset;
|
||||
|
||||
assign tdo_o = tdi_pad_i;
|
||||
assign shift_dr_o = shift_dr;
|
||||
assign pause_dr_o = pause_dr;
|
||||
assign update_dr_o = update_dr;
|
||||
assign capture_dr_o = capture_dr;
|
||||
|
||||
assign extest_select_o = extest_select;
|
||||
assign sample_preload_select_o = sample_preload_select;
|
||||
assign mbist_select_o = mbist_select;
|
||||
assign debug_select_o = debug_select;
|
||||
|
||||
|
||||
always @ (posedge tck_pad_i)
|
||||
begin
|
||||
tms_q1 <= tms_pad_i;
|
||||
tms_q2 <= tms_q1;
|
||||
tms_q3 <= tms_q2;
|
||||
tms_q4 <= tms_q3;
|
||||
end
|
||||
|
||||
|
||||
assign tms_reset = tms_q1 & tms_q2 & tms_q3 & tms_q4 & tms_pad_i; // 5 consecutive TMS=1 causes reset
|
||||
|
||||
|
||||
/**********************************************************************************
|
||||
* *
|
||||
* TAP State Machine: Fully JTAG compliant *
|
||||
* *
|
||||
**********************************************************************************/
|
||||
|
||||
// test_logic_reset state
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if(trst_pad_i)
|
||||
test_logic_reset<= 1'b1;
|
||||
else if (tms_reset)
|
||||
test_logic_reset<= 1'b1;
|
||||
else
|
||||
begin
|
||||
if(tms_pad_i & (test_logic_reset | select_ir_scan))
|
||||
test_logic_reset<= 1'b1;
|
||||
else
|
||||
test_logic_reset<= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
// run_test_idle state
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if(trst_pad_i)
|
||||
run_test_idle<= 1'b0;
|
||||
else if (tms_reset)
|
||||
run_test_idle<= 1'b0;
|
||||
else
|
||||
if(~tms_pad_i & (test_logic_reset | run_test_idle | update_dr | update_ir))
|
||||
run_test_idle<= 1'b1;
|
||||
else
|
||||
run_test_idle<= 1'b0;
|
||||
end
|
||||
|
||||
// select_dr_scan state
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if(trst_pad_i)
|
||||
select_dr_scan<= 1'b0;
|
||||
else if (tms_reset)
|
||||
select_dr_scan<= 1'b0;
|
||||
else
|
||||
if(tms_pad_i & (run_test_idle | update_dr | update_ir))
|
||||
select_dr_scan<= 1'b1;
|
||||
else
|
||||
select_dr_scan<= 1'b0;
|
||||
end
|
||||
|
||||
// capture_dr state
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if(trst_pad_i)
|
||||
capture_dr<= 1'b0;
|
||||
else if (tms_reset)
|
||||
capture_dr<= 1'b0;
|
||||
else
|
||||
if(~tms_pad_i & select_dr_scan)
|
||||
capture_dr<= 1'b1;
|
||||
else
|
||||
capture_dr<= 1'b0;
|
||||
end
|
||||
|
||||
// shift_dr state
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if(trst_pad_i)
|
||||
shift_dr<= 1'b0;
|
||||
else if (tms_reset)
|
||||
shift_dr<= 1'b0;
|
||||
else
|
||||
if(~tms_pad_i & (capture_dr | shift_dr | exit2_dr))
|
||||
shift_dr<= 1'b1;
|
||||
else
|
||||
shift_dr<= 1'b0;
|
||||
end
|
||||
|
||||
// exit1_dr state
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if(trst_pad_i)
|
||||
exit1_dr<= 1'b0;
|
||||
else if (tms_reset)
|
||||
exit1_dr<= 1'b0;
|
||||
else
|
||||
if(tms_pad_i & (capture_dr | shift_dr))
|
||||
exit1_dr<= 1'b1;
|
||||
else
|
||||
exit1_dr<= 1'b0;
|
||||
end
|
||||
|
||||
// pause_dr state
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if(trst_pad_i)
|
||||
pause_dr<= 1'b0;
|
||||
else if (tms_reset)
|
||||
pause_dr<= 1'b0;
|
||||
else
|
||||
if(~tms_pad_i & (exit1_dr | pause_dr))
|
||||
pause_dr<= 1'b1;
|
||||
else
|
||||
pause_dr<= 1'b0;
|
||||
end
|
||||
|
||||
// exit2_dr state
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if(trst_pad_i)
|
||||
exit2_dr<= 1'b0;
|
||||
else if (tms_reset)
|
||||
exit2_dr<= 1'b0;
|
||||
else
|
||||
if(tms_pad_i & pause_dr)
|
||||
exit2_dr<= 1'b1;
|
||||
else
|
||||
exit2_dr<= 1'b0;
|
||||
end
|
||||
|
||||
// update_dr state
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if(trst_pad_i)
|
||||
update_dr<= 1'b0;
|
||||
else if (tms_reset)
|
||||
update_dr<= 1'b0;
|
||||
else
|
||||
if(tms_pad_i & (exit1_dr | exit2_dr))
|
||||
update_dr<= 1'b1;
|
||||
else
|
||||
update_dr<= 1'b0;
|
||||
end
|
||||
|
||||
// select_ir_scan state
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if(trst_pad_i)
|
||||
select_ir_scan<= 1'b0;
|
||||
else if (tms_reset)
|
||||
select_ir_scan<= 1'b0;
|
||||
else
|
||||
if(tms_pad_i & select_dr_scan)
|
||||
select_ir_scan<= 1'b1;
|
||||
else
|
||||
select_ir_scan<= 1'b0;
|
||||
end
|
||||
|
||||
// capture_ir state
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if(trst_pad_i)
|
||||
capture_ir<= 1'b0;
|
||||
else if (tms_reset)
|
||||
capture_ir<= 1'b0;
|
||||
else
|
||||
if(~tms_pad_i & select_ir_scan)
|
||||
capture_ir<= 1'b1;
|
||||
else
|
||||
capture_ir<= 1'b0;
|
||||
end
|
||||
|
||||
// shift_ir state
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if(trst_pad_i)
|
||||
shift_ir<= 1'b0;
|
||||
else if (tms_reset)
|
||||
shift_ir<= 1'b0;
|
||||
else
|
||||
if(~tms_pad_i & (capture_ir | shift_ir | exit2_ir))
|
||||
shift_ir<= 1'b1;
|
||||
else
|
||||
shift_ir<= 1'b0;
|
||||
end
|
||||
|
||||
// exit1_ir state
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if(trst_pad_i)
|
||||
exit1_ir<= 1'b0;
|
||||
else if (tms_reset)
|
||||
exit1_ir<= 1'b0;
|
||||
else
|
||||
if(tms_pad_i & (capture_ir | shift_ir))
|
||||
exit1_ir<= 1'b1;
|
||||
else
|
||||
exit1_ir<= 1'b0;
|
||||
end
|
||||
|
||||
// pause_ir state
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if(trst_pad_i)
|
||||
pause_ir<= 1'b0;
|
||||
else if (tms_reset)
|
||||
pause_ir<= 1'b0;
|
||||
else
|
||||
if(~tms_pad_i & (exit1_ir | pause_ir))
|
||||
pause_ir<= 1'b1;
|
||||
else
|
||||
pause_ir<= 1'b0;
|
||||
end
|
||||
|
||||
// exit2_ir state
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if(trst_pad_i)
|
||||
exit2_ir<= 1'b0;
|
||||
else if (tms_reset)
|
||||
exit2_ir<= 1'b0;
|
||||
else
|
||||
if(tms_pad_i & pause_ir)
|
||||
exit2_ir<= 1'b1;
|
||||
else
|
||||
exit2_ir<= 1'b0;
|
||||
end
|
||||
|
||||
// update_ir state
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if(trst_pad_i)
|
||||
update_ir<= 1'b0;
|
||||
else if (tms_reset)
|
||||
update_ir<= 1'b0;
|
||||
else
|
||||
if(tms_pad_i & (exit1_ir | exit2_ir))
|
||||
update_ir<= 1'b1;
|
||||
else
|
||||
update_ir<= 1'b0;
|
||||
end
|
||||
|
||||
/**********************************************************************************
|
||||
* *
|
||||
* End: TAP State Machine *
|
||||
* *
|
||||
**********************************************************************************/
|
||||
|
||||
|
||||
|
||||
/**********************************************************************************
|
||||
* *
|
||||
* jtag_ir: JTAG Instruction Register *
|
||||
* *
|
||||
**********************************************************************************/
|
||||
reg [IR_LENGTH-1:0] jtag_ir; // Instruction register
|
||||
reg [IR_LENGTH-1:0] latched_jtag_ir, latched_jtag_ir_neg;
|
||||
reg instruction_tdo;
|
||||
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if(trst_pad_i)
|
||||
jtag_ir[IR_LENGTH-1:0] <= {IR_LENGTH{1'b0}};
|
||||
else if(capture_ir)
|
||||
jtag_ir <= 6'b000101; // This value is fixed for easier fault detection
|
||||
else if(shift_ir)
|
||||
jtag_ir[IR_LENGTH-1:0] <= {tdi_pad_i, jtag_ir[IR_LENGTH-1:1]};
|
||||
end
|
||||
|
||||
always @ (negedge tck_pad_i)
|
||||
begin
|
||||
instruction_tdo <= jtag_ir[0];
|
||||
end
|
||||
/**********************************************************************************
|
||||
* *
|
||||
* End: jtag_ir *
|
||||
* *
|
||||
**********************************************************************************/
|
||||
|
||||
|
||||
|
||||
/**********************************************************************************
|
||||
* *
|
||||
* idcode logic *
|
||||
* *
|
||||
**********************************************************************************/
|
||||
reg [31:0] idcode_reg;
|
||||
reg idcode_tdo;
|
||||
|
||||
always @ (posedge tck_pad_i)
|
||||
begin
|
||||
if(idcode_select & shift_dr)
|
||||
idcode_reg <= {tdi_pad_i, idcode_reg[31:1]};
|
||||
else
|
||||
idcode_reg <= IDCODE_VALUE;
|
||||
end
|
||||
|
||||
always @ (negedge tck_pad_i)
|
||||
begin
|
||||
idcode_tdo <= idcode_reg[0];
|
||||
end
|
||||
/**********************************************************************************
|
||||
* *
|
||||
* End: idcode logic *
|
||||
* *
|
||||
**********************************************************************************/
|
||||
|
||||
|
||||
/**********************************************************************************
|
||||
* *
|
||||
* Bypass logic *
|
||||
* *
|
||||
**********************************************************************************/
|
||||
reg bypassed_tdo;
|
||||
reg bypass_reg;
|
||||
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if (trst_pad_i)
|
||||
bypass_reg<= 1'b0;
|
||||
else if(shift_dr)
|
||||
bypass_reg<= tdi_pad_i;
|
||||
end
|
||||
|
||||
always @ (negedge tck_pad_i)
|
||||
begin
|
||||
bypassed_tdo <= bypass_reg;
|
||||
end
|
||||
/**********************************************************************************
|
||||
* *
|
||||
* End: Bypass logic *
|
||||
* *
|
||||
**********************************************************************************/
|
||||
|
||||
|
||||
/**********************************************************************************
|
||||
* *
|
||||
* Activating Instructions *
|
||||
* *
|
||||
**********************************************************************************/
|
||||
// Updating jtag_ir (Instruction Register)
|
||||
always @ (posedge tck_pad_i or posedge trst_pad_i)
|
||||
begin
|
||||
if(trst_pad_i)
|
||||
latched_jtag_ir <= IDCODE; // IDCODE selected after reset
|
||||
else if (tms_reset)
|
||||
latched_jtag_ir <= IDCODE; // IDCODE selected after reset
|
||||
else if(update_ir)
|
||||
latched_jtag_ir <= jtag_ir;
|
||||
end
|
||||
|
||||
/**********************************************************************************
|
||||
* *
|
||||
* End: Activating Instructions *
|
||||
* *
|
||||
**********************************************************************************/
|
||||
|
||||
|
||||
// Updating jtag_ir (Instruction Register)
|
||||
always @ (latched_jtag_ir)
|
||||
begin
|
||||
extest_select = 1'b0;
|
||||
sample_preload_select = 1'b0;
|
||||
idcode_select = 1'b0;
|
||||
mbist_select = 1'b0;
|
||||
debug_select = 1'b0;
|
||||
bypass_select = 1'b0;
|
||||
|
||||
case(latched_jtag_ir) /* synthesis parallel_case */
|
||||
EXTEST: extest_select = 1'b1; // External test
|
||||
SAMPLE_PRELOAD: sample_preload_select = 1'b1; // Sample preload
|
||||
IDCODE: idcode_select = 1'b1; // ID Code
|
||||
MBIST: mbist_select = 1'b1; // Mbist test
|
||||
DEBUG: debug_select = 1'b1; // Debug
|
||||
BYPASS: bypass_select = 1'b1; // BYPASS
|
||||
default: bypass_select = 1'b1; // BYPASS
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
|
||||
/**********************************************************************************
|
||||
* *
|
||||
* Multiplexing TDO data *
|
||||
* *
|
||||
**********************************************************************************/
|
||||
always @ (shift_ir_neg or exit1_ir or instruction_tdo or latched_jtag_ir_neg or idcode_tdo or
|
||||
debug_tdi_i or bs_chain_tdi_i or mbist_tdi_i or
|
||||
bypassed_tdo)
|
||||
begin
|
||||
if(shift_ir_neg)
|
||||
tdo_pad_o = instruction_tdo;
|
||||
else
|
||||
begin
|
||||
case(latched_jtag_ir_neg) // synthesis parallel_case
|
||||
IDCODE: tdo_pad_o = idcode_tdo; // Reading ID code
|
||||
DEBUG: tdo_pad_o = debug_tdi_i; // Debug
|
||||
SAMPLE_PRELOAD: tdo_pad_o = bs_chain_tdi_i; // Sampling/Preloading
|
||||
EXTEST: tdo_pad_o = bs_chain_tdi_i; // External test
|
||||
MBIST: tdo_pad_o = mbist_tdi_i; // Mbist test
|
||||
default: tdo_pad_o = bypassed_tdo; // BYPASS instruction
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// Tristate control for tdo_pad_o pin
|
||||
always @ (negedge tck_pad_i)
|
||||
begin
|
||||
tdo_padoe_o <= shift_ir | shift_dr | (pause_dr & debug_select);
|
||||
end
|
||||
/**********************************************************************************
|
||||
* *
|
||||
* End: Multiplexing TDO data *
|
||||
* *
|
||||
**********************************************************************************/
|
||||
|
||||
|
||||
always @ (negedge tck_pad_i)
|
||||
begin
|
||||
shift_ir_neg <= shift_ir;
|
||||
latched_jtag_ir_neg <= latched_jtag_ir;
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
@ -0,0 +1,53 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library work;
|
||||
use work.common.all;
|
||||
use work.wishbone_types.all;
|
||||
|
||||
entity logic_analyzer is
|
||||
generic (
|
||||
INPUT_IOS : integer range 0 to 32;
|
||||
OUTPUT_IOS : integer range 0 to 32
|
||||
);
|
||||
port (
|
||||
clk : in std_ulogic;
|
||||
rst : in std_ulogic;
|
||||
wb_in : in wb_io_master_out;
|
||||
wb_out : out wb_io_slave_out;
|
||||
io_in : in std_ulogic_vector(INPUT_IOS-1 downto 0);
|
||||
io_out : out std_ulogic_vector(OUTPUT_IOS-1 downto 0)
|
||||
);
|
||||
end logic_analyzer;
|
||||
|
||||
architecture rtl of logic_analyzer is
|
||||
signal we: std_ulogic;
|
||||
signal re: std_ulogic;
|
||||
signal ack: std_ulogic;
|
||||
begin
|
||||
-- Wishbone interface
|
||||
we <= wb_in.stb and wb_in.cyc and wb_in.we;
|
||||
re <= wb_in.stb and wb_in.cyc and not wb_in.we;
|
||||
wb_out.stall <= '0';
|
||||
wb_out.ack <= ack;
|
||||
|
||||
wb_0: process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
io_out <= (others => '0');
|
||||
ack <= '0';
|
||||
else
|
||||
if re = '1' then
|
||||
wb_out.dat(INPUT_IOS-1 downto 0) <= io_in;
|
||||
ack <= '1';
|
||||
elsif we = '1' then
|
||||
io_out <= wb_in.dat(INPUT_IOS-1 downto 0);
|
||||
ack <= '1';
|
||||
else
|
||||
ack <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
end architecture rtl;
|
@ -0,0 +1,929 @@
|
||||
-- Wishbone slave to packet bus
|
||||
|
||||
-- add way to reset (or do externally)
|
||||
-- not obeying sel on local writes yet!
|
||||
-- theoretically, this should work with slave-initiated packets like ints, even
|
||||
-- if they intervene within a pending master command (unpreventable because of
|
||||
-- concurrent xmits).
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.wishbone_types.all;
|
||||
use work.mc_pkg.all;
|
||||
|
||||
entity mc is
|
||||
|
||||
generic(
|
||||
WB_AW : integer := 32; -- wishbone_addr_bits
|
||||
WB_DW : integer := 64; -- wishbone_data_bits
|
||||
OIB_DW : integer := 8;
|
||||
OIB_RATIO : integer := 0; -- encode
|
||||
--WB_MAX_WR : integer := 1; -- could allow posted writes (no wait for ack)
|
||||
-- BAR_BITS : integer := 16; -- in mc_pkg
|
||||
BAR_INIT : std_ulogic_vector(BAR_BITS-1 downto 0) := x"FFFF" -- FFFFxxxx is local
|
||||
);
|
||||
port(
|
||||
clk : in std_ulogic;
|
||||
rst : in std_ulogic;
|
||||
|
||||
wb_cyc : in std_ulogic;
|
||||
wb_stb : in std_ulogic;
|
||||
wb_we : in std_ulogic;
|
||||
wb_addr : in std_ulogic_vector(WB_AW-1 downto 0);
|
||||
wb_wr_data : in std_ulogic_vector(WB_DW-1 downto 0);
|
||||
wb_sel : in std_ulogic_vector((WB_DW/8)-1 downto 0);
|
||||
wb_ack : out std_ulogic;
|
||||
wb_err : out std_ulogic;
|
||||
wb_stall : out std_ulogic;
|
||||
wb_rd_data : out std_ulogic_vector(WB_DW-1 downto 0);
|
||||
|
||||
oib_clk : out std_ulogic;
|
||||
ob_data : out std_ulogic_vector(OIB_DW-1 downto 0);
|
||||
ob_pty : out std_ulogic;
|
||||
|
||||
ib_data : in std_ulogic_vector(OIB_DW-1 downto 0);
|
||||
ib_pty : in std_ulogic;
|
||||
|
||||
err : out std_ulogic;
|
||||
int : out std_ulogic
|
||||
);
|
||||
end mc;
|
||||
|
||||
|
||||
architecture mc of mc is
|
||||
|
||||
-- ff
|
||||
signal config_d, config_q, config_rst: T_Config;
|
||||
signal config_data : std_ulogic_vector(WB_DW-1 downto 0);
|
||||
|
||||
signal wbseq_d, wbseq_q : std_ulogic_vector(3 downto 0);
|
||||
signal wb_in_d, wb_in_q : wishbone_master_out;
|
||||
signal wb_out_d, wb_out_q : wishbone_slave_out;
|
||||
|
||||
signal oclk_d, oclk_q : std_ulogic;
|
||||
signal oclk_last_d, oclk_last_q : std_ulogic;
|
||||
signal odata_d, odata_q : std_ulogic_vector(OIB_DW-1 downto 0);
|
||||
signal opty_d, opty_q : std_ulogic;
|
||||
signal oseq_d, oseq_q : std_ulogic_vector(3 downto 0);
|
||||
signal oclk_cnt_d, oclk_cnt_q : std_ulogic_vector(15 downto 0);
|
||||
signal odata_cnt_d, odata_cnt_q : std_ulogic_vector(2 downto 0);
|
||||
|
||||
signal idata_d, idata_q : std_ulogic_vector(OIB_DW-1 downto 0);
|
||||
signal ipty_d, ipty_q : std_ulogic;
|
||||
signal iseq_d, iseq_q : std_ulogic_vector(3 downto 0);
|
||||
signal icapture_d, icapture_q : std_ulogic;
|
||||
signal idata_cnt_d, idata_cnt_q : std_ulogic_vector(2 downto 0);
|
||||
|
||||
-- misc
|
||||
signal wbseq_err : std_ulogic;
|
||||
signal wb_req, wb_req_err, wb_local, wb_local_rd, wb_local_wr, wb_remote_rd, wb_remote_wr, wb_req_stall, wb_sync : std_ulogic;
|
||||
signal rd_data_load : std_ulogic_vector(WB_DW-1 downto 0);
|
||||
signal ob_busy, ob_stall : std_ulogic;
|
||||
signal local_rd_data : std_ulogic_vector(WB_DW-1 downto 0);
|
||||
signal ob_header : std_ulogic_vector(OIB_DW-1 downto 0);
|
||||
|
||||
signal oclk_advance, ob_complete, oseq_err, oseq_hold, iseq_err, rd_err, wr_err : std_ulogic;
|
||||
signal odata_clear, odata_advance, oaddr_last, odata_last, odata_ld_header, odata_ld_addr, odata_ld_sel, odata_ld_data : std_ulogic;
|
||||
signal oaddr_mux : std_ulogic_vector(7 downto 0);
|
||||
signal odata_mux : std_ulogic_vector(7 downto 0);
|
||||
signal ib_complete : std_ulogic;
|
||||
signal oclk_match : std_ulogic;
|
||||
signal oclk_toggle : std_ulogic_vector(15 downto 0);
|
||||
signal config_write : std_ulogic;
|
||||
signal wb_rd_resp, idata_clear : std_ulogic;
|
||||
signal link_req_o, link_rsp_o, link_req_i, link_rsp_i : std_ulogic;
|
||||
signal rd8_rsp, wr8_rsp, cache_inv, sync_ack, int_req : std_ulogic;
|
||||
signal bad_header, good_header, pty_err, ld_rd_data : std_ulogic;
|
||||
signal iseq_idle, idle_header, rd_rsp_data_done, rd_rsp_complete, wr_rsp_complete, int_req_complete, save_header : std_ulogic;
|
||||
|
||||
begin
|
||||
|
||||
-- these could sample the input bus for several of the bits on reset, but you need to know how wide the bus is
|
||||
-- maybe use another pin to determine if config_pins or hardcoded default are used
|
||||
--config_pins <=
|
||||
|
||||
config_rst <= (oib_en => '1', oib_width => bus_width_enc(OIB_DW), oib_ratio => bus_ratio_enc(OIB_RATIO), cpol => '0', cpha => '0',
|
||||
ib_en_pck => '1', rsvd0 => (others => '0'), int_req => '1', bar_en => '1',
|
||||
bar => BAR_INIT,
|
||||
rsvd1 => (others => '0'),
|
||||
idle_flit => (others => '0'), rcv_header => (others => '0'),
|
||||
err => (others => '0')
|
||||
);
|
||||
|
||||
config_data <= config_q.oib_en & config_q.oib_width & config_q.oib_ratio & -- 63:56
|
||||
config_q.cpol & config_q.cpha & config_q.ib_en_pck & config_q.rsvd0 & config_q.int_req & config_q.bar_en & -- 55:48
|
||||
config_q.bar & -- 47:32
|
||||
config_q.rsvd1 & -- 31:24
|
||||
config_q.idle_flit & config_q.rcv_header & -- 23:08
|
||||
config_q.err; -- 07:00
|
||||
|
||||
int <= config_q.int_req;
|
||||
--err <= or_reduce(config_q.err);
|
||||
err <= config_q.err(7) or config_q.err(6) or config_q.err(5) or config_q.err(4) or config_q.err(3) or config_q.err(2) or config_q.err(1) or config_q.err(0);
|
||||
|
||||
-- normal FF
|
||||
FF: process(clk) begin
|
||||
|
||||
if rising_edge(clk) then
|
||||
|
||||
if rst = '1' then
|
||||
|
||||
config_q <= config_rst;
|
||||
wb_in_q <= wishbone_master_out_init;
|
||||
wb_out_q <= wishbone_slave_out_init;
|
||||
oclk_q <= '0';
|
||||
oclk_last_q <= '0';
|
||||
odata_q <= (others => '0');
|
||||
opty_q <= '1';
|
||||
wbseq_q <= (others => '1');
|
||||
oseq_q <= (others => '1');
|
||||
iseq_q <= (others => '1');
|
||||
oclk_cnt_q <= (others => '0');
|
||||
odata_cnt_q <= (others => '0');
|
||||
idata_cnt_q <= (others => '0');
|
||||
icapture_q <= '0';
|
||||
idata_q <= (others => '0');
|
||||
ipty_q <= '1';
|
||||
|
||||
else
|
||||
|
||||
config_q <= config_d;
|
||||
wb_in_q <= wb_in_d;
|
||||
wb_out_q <= wb_out_d;
|
||||
oclk_q <= oclk_d;
|
||||
oclk_last_q <= oclk_last_d;
|
||||
odata_q <= odata_d;
|
||||
opty_q <= opty_d;
|
||||
wbseq_q <= wbseq_d;
|
||||
oseq_q <= oseq_d;
|
||||
iseq_q <= iseq_d;
|
||||
oclk_cnt_q <= oclk_cnt_d;
|
||||
odata_cnt_q <= odata_cnt_d;
|
||||
idata_cnt_q <= idata_cnt_d;
|
||||
icapture_q <= icapture_d;
|
||||
idata_q <= idata_d;
|
||||
ipty_q <= ipty_d;
|
||||
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
end process FF;
|
||||
|
||||
-- do something
|
||||
|
||||
-- latch master - cyc/stb should be a single valid
|
||||
|
||||
wb_req <= wb_cyc and wb_stb and not wb_out_q.stall;
|
||||
wb_in_d.cyc <= '1' when wb_req = '1' else (wb_in_q.cyc and not wb_out_q.ack);
|
||||
wb_in_d.stb <= '1' when wb_req = '1' else (wb_in_q.stb and not wb_out_q.ack);
|
||||
wb_in_d.we <= wb_we when wb_req = '1' else wb_in_q.we;
|
||||
wb_in_d.adr <= wb_addr when wb_req = '1' else wb_in_q.adr;
|
||||
wb_in_d.dat <= wb_wr_data when wb_req = '1' else wb_in_q.dat;
|
||||
wb_in_d.sel <= wb_sel when wb_req = '1' else wb_in_q.sel;
|
||||
|
||||
-- process req
|
||||
|
||||
-- move to unlatched
|
||||
--wb_local <= config_q.bar_en and eq(wb_in_q.adr(WB_AW-1 downto WB_AW-BAR_BITS), config_q.bar);
|
||||
wb_local <= config_q.bar_en and eq(wb_addr(WB_AW-1 downto WB_AW-BAR_BITS), config_q.bar);
|
||||
|
||||
-- should be able to ack immediately rather than send latched (skip ack cycle in seq, send _d)
|
||||
|
||||
--tbl WBSlaveSeq
|
||||
--n wbseq_q wbseq_d
|
||||
--n | wb_req |
|
||||
--n | | | wb_local_rd
|
||||
--n | | wb_we | |wb_local_wr
|
||||
--n | | | | ||wb_remote_rd
|
||||
--n | | | | |||wb_remote_wr
|
||||
--n | | | | |||| wb_out_d.stall
|
||||
--n | | | wb_local | |||| |wb_out_d.ack
|
||||
--n | | | | ob_complete | |||| || oseq_hold
|
||||
--n | | | | |rd_rsp_complete | |||| || |
|
||||
--n | | | | ||wr_rsp_complete | |||| || |
|
||||
--n | | | | ||| | |||| || | wbseq_err
|
||||
--b 3210 | | | ||| 3210 |||| || | |
|
||||
--t iiii i i i iii oooo oooo oo o o
|
||||
--*--------------------------------------------------------------------------------------------------------------------
|
||||
--*-- Idle ------------------------------------------------------------------------------------------------------------
|
||||
--s 1111 0 - - --- 1111 0000 00 0 0 * zzz..zzz....
|
||||
--s 1111 1 0 1 --- 0001 1000 10 0 0 * read local
|
||||
--s 1111 1 1 1 --- 0010 0100 10 0 0 * write local
|
||||
--s 1111 1 0 0 --- 0100 0010 10 0 0 * read remote
|
||||
--s 1111 1 1 0 --- 1000 0001 10 0 0 * write remote
|
||||
--*-- Read Local ------------------------------------------------------------------------------------------------------
|
||||
--s 0001 - - - --- 1110 0000 11 0 0 * read ack
|
||||
--*-- Write Local -----------------------------------------------------------------------------------------------------
|
||||
--s 0010 - - - --- 1110 0000 11 0 0 * write ack
|
||||
--*-- Read Remote -----------------------------------------------------------------------------------------------------
|
||||
--s 0100 - - - --- ---- 0010 10 0 0 *
|
||||
--s 0100 - - - 0-- 0100 ---- -- - - * read send
|
||||
--s 0100 - - - 1-- 0101 ---- -- - - * read sent
|
||||
--*-- Read Remote Wait ------------------------------------------------------------------------------------------------
|
||||
--s 0101 - - - --- ---- 0010 10 1 0 *
|
||||
--s 0101 - - - -0- 0101 ---- -- - - * wait for response
|
||||
--s 0101 - - - -1- 0110 ---- -- - - * response received
|
||||
--*-- Read Remote Done-------------------------------------------------------------------------------------------------
|
||||
--s 0110 - - - -0- 1110 0010 11 1 0 * read ack
|
||||
--*-- Write Remote ----------------------------------------------------------------------------------------------------
|
||||
--s 1000 - - - --- ---- 0001 10 0 0 *
|
||||
--s 1000 - - - 0-- 1000 ---- -- - - * write send
|
||||
--s 1000 - - - 1-- 1001 ---- -- - - * write sent
|
||||
--*-- Write Remote Wait -----------------------------------------------------------------------------------------------
|
||||
--s 1001 - - - --- ---- 0001 10 1 0 *
|
||||
--s 1001 - - - --0 1001 ---- -- - - * wait for response
|
||||
--s 1001 - - - --1 1010 ---- -- - - * response received
|
||||
--*-- Write Remote Done -----------------------------------------------------------------------------------------------
|
||||
--s 1010 - - - --- 1110 0000 11 1 0 * write ack
|
||||
--*-- Ack Cycle -------------------------------------------------------------------------------------------------------
|
||||
--s 1110 - - - --- 1111 0000 00 1 0 * last cycle of stall; ack=1
|
||||
--*-- ERROR -----------------------------------------------------------------------------------------------------------
|
||||
--s 0000 - - - --- 0000 0000 00 0 1
|
||||
--s 0011 - - - --- 0011 0000 00 0 1
|
||||
--s 0111 - - - --- 0111 0000 00 0 1
|
||||
--s 1011 - - - --- 1011 0000 00 0 1
|
||||
--s 1100 - - - --- 1100 0000 00 0 1
|
||||
--s 1101 - - - --- 1101 0000 00 0 1
|
||||
--*--------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--tbl WBSlaveSeq
|
||||
|
||||
-- local
|
||||
|
||||
-- move to unlatched
|
||||
--config_write <= wb_local_wr and eq(wb_in_q.adr(31-BAR_BITS downto 0), 0);
|
||||
config_write <= wb_local_wr and eq(wb_addr(31-BAR_BITS downto 0), 0);
|
||||
|
||||
config_d.oib_en <= wb_in_d.dat(63) when config_write = '1' else config_q.oib_en;
|
||||
config_d.oib_ratio <= wb_in_d.dat(62 downto 59) when config_write = '1' else config_q.oib_ratio;
|
||||
config_d.oib_width <= wb_in_d.dat(58 downto 56) when config_write = '1' else config_q.oib_width;
|
||||
config_d.cpol <= wb_in_d.dat(55) when config_write = '1' else config_q.cpol;
|
||||
config_d.cpha <= wb_in_d.dat(54) when config_write = '1' else config_q.cpha;
|
||||
config_d.ib_en_pck <= wb_in_d.dat(50) when config_write = '1' else config_q.ib_en_pck;
|
||||
config_d.rsvd0 <= wb_in_d.dat(53 downto 51) when config_write = '1' else config_q.rsvd0;
|
||||
config_d.int_req <= wb_in_d.dat(49) when config_write = '1' else (config_q.int_req or int_req_complete);
|
||||
config_d.bar_en <= wb_in_d.dat(48) when config_write = '1' else config_q.bar_en;
|
||||
config_d.bar <= wb_in_d.dat(47 downto 32) when config_write = '1' else config_q.bar;
|
||||
config_d.rsvd1 <= wb_in_d.dat(31 downto 24) when config_write = '1' else config_q.rsvd1;
|
||||
config_d.idle_flit <= wb_in_d.dat(23 downto 16) when config_write = '1' else config_q.idle_flit;
|
||||
-- or write once until cleared?
|
||||
config_d.rcv_header <= wb_in_d.dat(15 downto 8) when config_write = '1' else
|
||||
gate_and(save_header, idata_q) or gate_and(not save_header, config_q.rcv_header);
|
||||
|
||||
config_d.err <= wb_in_d.dat(7 downto 0) when config_write = '1' else
|
||||
(config_q.err(7) or wbseq_err) & (config_q.err(6) or oseq_err) & (config_q.err(5) or iseq_err) & (config_q.err(4) or rd_err) &
|
||||
(config_q.err(3) or wr_err) & (config_q.err(2) or pty_err) & (config_q.err(1) or bad_header) & config_q.err(0);
|
||||
|
||||
-- outputs
|
||||
wb_stall <= wb_out_q.stall;
|
||||
wb_ack <= wb_out_q.ack;
|
||||
wb_rd_data <= wb_out_q.dat;
|
||||
wb_err <= '0';
|
||||
|
||||
-- send
|
||||
|
||||
wb_sync <= '0';
|
||||
link_req_o <= '0';
|
||||
link_rsp_o <= '0';
|
||||
|
||||
--tbl HeaderEncode
|
||||
--n wb_remote_rd ob_header
|
||||
--n |wb_remote_wr |
|
||||
--n ||wb_sync |
|
||||
--n ||| link_req_o |
|
||||
--n ||| |link_rsp_o |
|
||||
--n ||| || |
|
||||
--n ||| || |
|
||||
--b ||| || 76543210
|
||||
--t iii ii oooooooo
|
||||
--*-------------------------------------------------
|
||||
--s 1-- -- 00000010 * read 8B
|
||||
--s -1- -- 00000011 * write 8B
|
||||
--s --1 -- 01000000 * sync and code
|
||||
--s --- 1- 11110000 * link req and code
|
||||
--s --- -1 11111000 * link rsp and code
|
||||
--*-------------------------------------------------
|
||||
|
||||
--tbl HeaderEncode
|
||||
|
||||
-- bus clock
|
||||
|
||||
with config_q.oib_ratio select
|
||||
oclk_toggle <= x"0000" when "0000", -- toggle every clk 2:1 * fails right now *
|
||||
x"0001" when "0001", -- toggle every 2 4:1
|
||||
x"0002" when "0010", -- toggle every 3 6:1
|
||||
x"0004" when "0011", -- toggle every 5 10:1
|
||||
x"0008" when "0100", -- toggle every 9 18:1
|
||||
x"0010" when "0101", -- toggle every 17 34:1
|
||||
x"0020" when "0110", -- toggle every 33 66:1
|
||||
x"0040" when "0111", -- toggle every 65 130:1
|
||||
x"0080" when "1000", -- toggle every 129 258:1
|
||||
x"0100" when "1001", -- toggle every 257 514:1
|
||||
x"0200" when others; -- toggle every 513 1026:1
|
||||
|
||||
oclk_match <= eq(oclk_cnt_q, oclk_toggle);
|
||||
|
||||
oclk_cnt_d <= gate_and(not config_q.oib_en or config_write, x"0000") or
|
||||
gate_and(config_q.oib_en and not config_write and oclk_match, x"0000") or
|
||||
gate_and(config_q.oib_en and not config_write and not oclk_match, inc(oclk_cnt_q));
|
||||
|
||||
oclk_advance <= oclk_match and oclk_q;
|
||||
|
||||
oib_clk <= oclk_q;
|
||||
|
||||
oclk_d <= (oclk_q xor oclk_match) and config_q.oib_en;
|
||||
oclk_last_d <= oclk_q and config_q.oib_en;
|
||||
|
||||
-- cpol not used; clock always running
|
||||
|
||||
with config_q.cpha select
|
||||
icapture_d <= not oclk_last_q and oclk_q and config_q.oib_en when '0', -- rising
|
||||
oclk_last_q and not oclk_q and config_q.oib_en when others; -- falling
|
||||
|
||||
-- output
|
||||
|
||||
--tbl SendSeq
|
||||
--
|
||||
--n oseq_q oseq_d
|
||||
--n | oseq_hold |
|
||||
--n | |wb_remote_rd | odata_ld_header
|
||||
--n | ||wb_remote_wr | |odata_ld_addr
|
||||
--n | ||| | ||odata_ld_sel
|
||||
--n | ||| oclk_advance | |||odata_clear
|
||||
--n | ||| |oaddr_last | ||||odata_ld_data
|
||||
--n | ||| ||odata_last | ||||| ob_complete
|
||||
--n | ||| ||| | ||||| |
|
||||
--n | ||| ||| | ||||| | oseq_err
|
||||
--b 3210 ||| ||| 3210 ||||| | |
|
||||
--t iiii iii iii oooo ooooo o o
|
||||
--*-------------------------------------------------------------------------------------------------------------------
|
||||
--*-- Idle -----------------------------------------------------------------------------------------------------------
|
||||
--s 1111 1-- --- 1111 00010 0 0 * zzz..zzz...
|
||||
--s 1111 -00 --- 1111 00010 0 0 * zzz..zzz...
|
||||
--s 1111 0-- 0-- 1111 00010 0 0 * ...slow...
|
||||
--s 1111 01- 1-- 0001 10000 0 0 * start read
|
||||
--s 1111 0-1 1-- 0001 10000 0 0 * start write
|
||||
--*-- Remote Header --------------------------------------------------------------------------------------------------
|
||||
--s 0001 --- 0-- 0001 00000 0 0 * ...slow...
|
||||
--s 0001 -1- 1-- 0010 01000 0 0 * begin address
|
||||
--s 0001 --1 1-- 0010 01000 0 0 * begin address
|
||||
--*-- Remote Address -------------------------------------------------------------------------------------------------
|
||||
--s 0010 --- 0-- 0010 01000 0 0 * ...slow...
|
||||
--s 0010 --- 10- 0010 01000 0 0 * sending addr
|
||||
--s 0010 --0 11- 1111 00010 1 0 * finish read request
|
||||
--s 0010 --1 11- 0011 00110 0 0 * begin write sel
|
||||
--*-- Remote Write (Sel) ---------------------------------------------------------------------------------------------
|
||||
--s 0011 --- 0-- 0011 00000 0 0 * ...slow...
|
||||
--s 0011 --- 1-- 0100 00001 0 0 * begin write data
|
||||
--*-- Remote Write (Data) --------------------------------------------------------------------------------------------
|
||||
--s 0100 --- 0-- 0100 00001 0 0 * ...slow...
|
||||
--s 0100 --- 1-0 0100 00001 0 0 * sending data
|
||||
--s 0100 --- 1-1 1111 00001 1 0 * finish write request
|
||||
--*-- ERROR ----------------------------------------------------------------------------------------------------------
|
||||
--s 0000 --- --- 0000 00000 0 1
|
||||
--s 0101 --- --- 0101 00000 0 1
|
||||
--s 0110 --- --- 0110 00000 0 1
|
||||
--s 0111 --- --- 0111 00000 0 1
|
||||
--s 1000 --- --- 1000 00000 0 1
|
||||
--s 1001 --- --- 1001 00000 0 1
|
||||
--s 1010 --- --- 1010 00000 0 1
|
||||
--s 1011 --- --- 1011 00000 0 1
|
||||
--s 1100 --- --- 1100 00000 0 1
|
||||
--s 1101 --- --- 1101 00000 0 1
|
||||
--s 1110 --- --- 1110 00000 0 1
|
||||
--*-------------------------------------------------------------------------------------------------------------------
|
||||
--tbl SendSeq
|
||||
|
||||
|
||||
-- 4 xfer for addr, 8 xfer for data
|
||||
odata_cnt_d <= gate_and(odata_clear, "000") or
|
||||
gate_and(odata_advance and odata_ld_addr, inc(odata_cnt_q)) or -- no clear?
|
||||
gate_and(odata_advance and odata_ld_data, inc(odata_cnt_q)) or -- no clear?
|
||||
gate_and(not odata_clear and not(odata_advance and (odata_ld_addr or odata_ld_data)), odata_cnt_q);
|
||||
|
||||
oaddr_last <= eq(odata_cnt_q, 4);
|
||||
odata_last <= eq(odata_cnt_q, 7);
|
||||
|
||||
with odata_cnt_q select
|
||||
oaddr_mux <= wb_in_q.adr(7 downto 0) when "000",
|
||||
wb_in_q.adr(15 downto 8) when "001",
|
||||
wb_in_q.adr(23 downto 16) when "010",
|
||||
wb_in_q.adr(31 downto 24) when others;
|
||||
|
||||
with odata_cnt_q select
|
||||
odata_mux <= wb_in_q.dat(7 downto 0) when "000",
|
||||
wb_in_q.dat(15 downto 8) when "001",
|
||||
wb_in_q.dat(23 downto 16) when "010",
|
||||
wb_in_q.dat(31 downto 24) when "011",
|
||||
wb_in_q.dat(39 downto 32) when "100",
|
||||
wb_in_q.dat(47 downto 40) when "101",
|
||||
wb_in_q.dat(55 downto 48) when "110",
|
||||
wb_in_q.dat(63 downto 56) when others;
|
||||
|
||||
--wtf fix this to look normal
|
||||
odata_d <= gate_and(odata_clear and odata_advance, config_q.idle_flit) or
|
||||
gate_and(odata_ld_header, ob_header) or
|
||||
gate_and(odata_ld_addr and odata_advance, oaddr_mux) or
|
||||
gate_and(odata_ld_sel, wb_in_q.sel) or
|
||||
gate_and(odata_ld_data and odata_advance, odata_mux) or
|
||||
gate_and(not odata_ld_header and not odata_ld_sel and
|
||||
not(odata_ld_addr and odata_advance) and
|
||||
not odata_ld_sel and
|
||||
not(odata_ld_data and odata_advance) and
|
||||
not(odata_clear and odata_advance), odata_q);
|
||||
|
||||
opty_d <= not(odata_d(7) xor odata_d(6) xor odata_d(5) xor odata_d(4) xor odata_d(3) xor odata_d(2) xor odata_d(1) xor odata_d(0));
|
||||
|
||||
odata_advance <= oclk_advance; -- oclk_match and not oclk_q and odata_ld_data;
|
||||
|
||||
ob_data <= odata_q;
|
||||
ob_pty <= opty_q;
|
||||
|
||||
-- input
|
||||
|
||||
with icapture_d select
|
||||
idata_d <= ib_data when '1',
|
||||
idata_q when others;
|
||||
|
||||
with icapture_d select
|
||||
ipty_d <= ib_pty when '1',
|
||||
ipty_q when others;
|
||||
|
||||
|
||||
--tbl HeaderDecode
|
||||
--n idata_q wb_remote_rd rd8_rsp
|
||||
--n | |wb_remote_wr |wr8_rsp
|
||||
--n | || ||int_req
|
||||
--n | || |||sync_ack
|
||||
--n | || ||||cache_inv
|
||||
--n | || |||||link_req_i
|
||||
--n | || ||||||link_rsp_i
|
||||
--n | || |||||||
|
||||
--n | || ||||||| good_header
|
||||
--n | || ||||||| |
|
||||
--b 76543210 || ||||||| |
|
||||
--t iiiiiiii ii ooooooo o
|
||||
--*-------------------------------------------------
|
||||
--s 1000--10 1- 1000000 1 * read 8B resp and code
|
||||
--s 1000--11 -1 0100000 1 * write 8B ack and code
|
||||
--s 11000--- -- 0001000 1 * sync_ack and code (thread, type, etc.)
|
||||
--s 11001--- -- 0000100 1 * cache inv
|
||||
--s 11010--- -- 0010000 1 * int_req and code (ext, crit, stop, fry)
|
||||
--s 11110--- -- 0000010 1 * link req and code
|
||||
--s 11111--- -- 0000001 1 * link rsp and code
|
||||
--*-------------------------------------------------
|
||||
--tbl HeaderDecode
|
||||
|
||||
idle_header <= eq(idata_q, config_q.idle_flit);
|
||||
bad_header <= iseq_idle and icapture_q and not idle_header and not good_header;
|
||||
pty_err <= icapture_q and not(idata_q(0) xor idata_q(1) xor idata_q(2) xor idata_q(3) xor idata_q(4) xor idata_q(5) xor idata_q(6) xor idata_q(7) xor ipty_q);
|
||||
|
||||
|
||||
--tbl RecvSeq
|
||||
--
|
||||
--n iseq_q iseq_d
|
||||
--n | icapture_q |
|
||||
--n | |idle_header | ld_rd_data
|
||||
--n | ||rd8_rsp | |rd_rsp_complete
|
||||
--n | |||wr8_rsp | ||wr_rsp_complete
|
||||
--n | ||||int_req | |||int_req_complete
|
||||
--n | |||||sync_ack | ||||
|
||||
--n | ||||||cache_inv | ||||
|
||||
--n | |||||||link_req_i | ||||
|
||||
--n | ||||||||link_rsp_i | |||| idata_clear
|
||||
--n | ||||||||| bad_header | |||| |save_header
|
||||
--n | ||||||||| | | |||| ||
|
||||
--n | ||||||||| | rd_rsp_data_done | |||| || iseq_idle
|
||||
--n | ||||||||| | | | |||| || |iseq_err
|
||||
--b 3210 ||||||||| | | 3210 |||| || ||
|
||||
--t iiii iiiiiiiii i i oooo oooo oo oo
|
||||
--*-------------------------------------------------------------------------------------------------------------------
|
||||
--*-- Idle -----------------------------------------------------------------------------------------------------------
|
||||
--s 1111 --------- - - ---- ---- -- 10
|
||||
--s 1111 0-------- - - 1111 0000 10 -- * zzz..zzz...
|
||||
--s 1111 11------- - - 1111 0000 10 -- * idle
|
||||
--s 1111 1-------- 1 - 0110 0000 00 -- * bad header
|
||||
--s 1111 1-1------ - - 1000 0000 00 -- * rd8 response
|
||||
--s 1111 1--1----- - - 0001 0000 00 -- * wr8 ack
|
||||
--s 1111 1---1---- - - 0010 0000 00 -- * int req
|
||||
--s 1111 1----1--- - - 0110 0000 00 -- * other response
|
||||
--s 1111 1-----1-- - - 0110 0000 00 -- * other response
|
||||
--s 1111 1------1- - - 0110 0000 00 -- * other response
|
||||
--s 1111 1-------1 - - 0110 0000 00 -- * other response
|
||||
--*-- Rd Resp --------------------------------------------------------------------------------------------------------
|
||||
--s 1000 0 ------- - - 1000 0000 00 00 * ...slow...
|
||||
--s 1000 1 ------- - 0 1000 1000 00 00 * Dx
|
||||
--s 1000 1 ------- - 1 1111 1100 00 00 * Dlast
|
||||
--*-- Wr Ack ---------------------------------------------------------------------------------------------------------
|
||||
--s 0001 - ------- - - 1111 0010 00 00 * ack + code
|
||||
--*-- Int Req --------------------------------------------------------------------------------------------------------
|
||||
--s 0010 - ------- - - 1111 0001 01 00 * int + code
|
||||
--*-- Unknown Header -------------------------------------------------------------------------------------------------
|
||||
--s 0110 - ------- - - 0111 0000 01 00 * save header and wait for idle bus
|
||||
--*-- Wait for Idle --------------------------------------------------------------------------------------------------
|
||||
--s 0111 0 ------- - - 0110 0000 00 00 * ...slow...
|
||||
--s 0111 11------- - - 1111 0000 00 00 * idle
|
||||
--s 0111 10------- - - 0110 0000 00 00 * non-idle
|
||||
--*-- ERROR ----------------------------------------------------------------------------------------------------------
|
||||
--s 0000 --------- - - 0000 0000 00 01
|
||||
--s 0011 --------- - - 0011 0000 00 01
|
||||
--s 0100 --------- - - 0100 0000 00 01
|
||||
--s 0101 --------- - - 0101 0000 00 01
|
||||
--s 1001 --------- - - 1001 0000 00 01
|
||||
--s 1010 --------- - - 1010 0000 00 01
|
||||
--s 1011 --------- - - 1011 0000 00 01
|
||||
--s 1100 --------- - - 1100 0000 00 01
|
||||
--s 1101 --------- - - 1101 0000 00 01
|
||||
--s 1110 --------- - - 1110 0000 00 01
|
||||
--*-------------------------------------------------------------------------------------------------------------------
|
||||
--tbl RecvSeq
|
||||
|
||||
|
||||
-- read data
|
||||
-- load immediately with local data
|
||||
-- load 0:n for ib data
|
||||
idata_cnt_d <= gate_and(icapture_q and ld_rd_data, inc(idata_cnt_q)) or
|
||||
gate_and(not idata_clear and not(icapture_q and ld_rd_data), idata_cnt_q);
|
||||
|
||||
rd_rsp_data_done <= eq(idata_cnt_q, 7);
|
||||
|
||||
with wb_in_q.adr(7 downto 4) select
|
||||
local_rd_data <= config_data when "0000",
|
||||
(others => '1') when others;
|
||||
|
||||
with idata_cnt_q select
|
||||
rd_data_load <= wb_out_q.dat(63 downto 8) & idata_q when "000",
|
||||
wb_out_q.dat(63 downto 16) & idata_q & wb_out_q.dat(7 downto 0) when "001",
|
||||
wb_out_q.dat(63 downto 24) & idata_q & wb_out_q.dat(15 downto 0) when "010",
|
||||
wb_out_q.dat(63 downto 32) & idata_q & wb_out_q.dat(23 downto 0) when "011",
|
||||
wb_out_q.dat(63 downto 40) & idata_q & wb_out_q.dat(31 downto 0) when "100",
|
||||
wb_out_q.dat(63 downto 48) & idata_q & wb_out_q.dat(39 downto 0) when "101",
|
||||
wb_out_q.dat(63 downto 56) & idata_q & wb_out_q.dat(47 downto 0) when "110",
|
||||
idata_q & wb_out_q.dat(55 downto 0) when others;
|
||||
|
||||
wb_out_d.dat <= gate_and(wb_local_rd, local_rd_data) or
|
||||
gate_and(wb_remote_rd and ld_rd_data, rd_data_load) or
|
||||
gate_and(not wb_local_rd and not (wb_remote_rd and ld_rd_data), wb_out_q.dat);
|
||||
|
||||
rd_err <= rd8_rsp and iseq_idle and icapture_q and not(eq(idata_q(4 downto 3), 0));
|
||||
wr_err <= wr8_rsp and iseq_idle and icapture_q and not(eq(idata_q(4 downto 3), 0));
|
||||
|
||||
---------------- Generated --------------------------
|
||||
|
||||
--vtable HeaderEncode
|
||||
ob_header(7) <=
|
||||
(link_req_o) or
|
||||
(link_rsp_o);
|
||||
ob_header(6) <=
|
||||
(wb_sync) or
|
||||
(link_req_o) or
|
||||
(link_rsp_o);
|
||||
ob_header(5) <=
|
||||
(link_req_o) or
|
||||
(link_rsp_o);
|
||||
ob_header(4) <=
|
||||
(link_req_o) or
|
||||
(link_rsp_o);
|
||||
ob_header(3) <=
|
||||
(link_rsp_o);
|
||||
ob_header(2) <= '0';
|
||||
ob_header(1) <=
|
||||
(wb_remote_rd) or
|
||||
(wb_remote_wr);
|
||||
ob_header(0) <=
|
||||
(wb_remote_wr);
|
||||
--vtable HeaderEncode
|
||||
|
||||
--vtable HeaderDecode
|
||||
rd8_rsp <=
|
||||
(idata_q(7) and not idata_q(6) and not idata_q(5) and not idata_q(4) and idata_q(1) and not idata_q(0) and wb_remote_rd);
|
||||
wr8_rsp <=
|
||||
(idata_q(7) and not idata_q(6) and not idata_q(5) and not idata_q(4) and idata_q(1) and idata_q(0) and wb_remote_wr);
|
||||
int_req <=
|
||||
(idata_q(7) and idata_q(6) and not idata_q(5) and idata_q(4) and not idata_q(3));
|
||||
sync_ack <=
|
||||
(idata_q(7) and idata_q(6) and not idata_q(5) and not idata_q(4) and not idata_q(3));
|
||||
cache_inv <=
|
||||
(idata_q(7) and idata_q(6) and not idata_q(5) and not idata_q(4) and idata_q(3));
|
||||
link_req_i <=
|
||||
(idata_q(7) and idata_q(6) and idata_q(5) and idata_q(4) and not idata_q(3));
|
||||
link_rsp_i <=
|
||||
(idata_q(7) and idata_q(6) and idata_q(5) and idata_q(4) and idata_q(3));
|
||||
good_header <=
|
||||
(idata_q(7) and not idata_q(6) and not idata_q(5) and not idata_q(4) and idata_q(1) and not idata_q(0) and wb_remote_rd) or
|
||||
(idata_q(7) and not idata_q(6) and not idata_q(5) and not idata_q(4) and idata_q(1) and idata_q(0) and wb_remote_wr) or
|
||||
(idata_q(7) and idata_q(6) and not idata_q(5) and not idata_q(4) and not idata_q(3)) or
|
||||
(idata_q(7) and idata_q(6) and not idata_q(5) and not idata_q(4) and idata_q(3)) or
|
||||
(idata_q(7) and idata_q(6) and not idata_q(5) and idata_q(4) and not idata_q(3)) or
|
||||
(idata_q(7) and idata_q(6) and idata_q(5) and idata_q(4) and not idata_q(3)) or
|
||||
(idata_q(7) and idata_q(6) and idata_q(5) and idata_q(4) and idata_q(3));
|
||||
--vtable HeaderDecode
|
||||
|
||||
--vtable WBSlaveSeq
|
||||
wbseq_d(3) <=
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and not wb_req) or
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and wb_we and not wb_local) or
|
||||
(not wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or
|
||||
(not wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0) and not rd_rsp_complete) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0) and not ob_complete) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0) and ob_complete) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0) and not wr_rsp_complete) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0) and wr_rsp_complete) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or
|
||||
(wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0)) or
|
||||
(wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0));
|
||||
wbseq_d(2) <=
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and not wb_req) or
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and not wb_we and not wb_local) or
|
||||
(not wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or
|
||||
(not wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0) and not ob_complete) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0) and ob_complete) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0) and not rd_rsp_complete) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0) and rd_rsp_complete) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0) and not rd_rsp_complete) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or
|
||||
(wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0)) or
|
||||
(wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0));
|
||||
wbseq_d(1) <=
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and not wb_req) or
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and wb_we and wb_local) or
|
||||
(not wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or
|
||||
(not wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0) and rd_rsp_complete) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0) and not rd_rsp_complete) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0) and wr_rsp_complete) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or
|
||||
(not wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and wbseq_q(0));
|
||||
wbseq_d(0) <=
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and not wb_req) or
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and not wb_we and wb_local) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0) and ob_complete) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0) and not rd_rsp_complete) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0) and ob_complete) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0) and not wr_rsp_complete) or
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or
|
||||
(not wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or
|
||||
(wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0));
|
||||
wb_local_rd <=
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and not wb_we and wb_local);
|
||||
wb_local_wr <=
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and wb_we and wb_local);
|
||||
wb_remote_rd <=
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and not wb_we and not wb_local) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0)) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0) and not rd_rsp_complete);
|
||||
wb_remote_wr <=
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and wb_we and not wb_local) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0)) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0));
|
||||
wb_out_d.stall <=
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and not wb_we and wb_local) or
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and wb_we and wb_local) or
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and not wb_we and not wb_local) or
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0) and wb_req and wb_we and not wb_local) or
|
||||
(not wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or
|
||||
(not wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0)) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0) and not rd_rsp_complete) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0)) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0));
|
||||
wb_out_d.ack <=
|
||||
(not wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or
|
||||
(not wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0) and not rd_rsp_complete) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0));
|
||||
oseq_hold <=
|
||||
(not wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0) and not rd_rsp_complete) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and wbseq_q(0)) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and not wbseq_q(0)) or
|
||||
(wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and not wbseq_q(0));
|
||||
wbseq_err <=
|
||||
(not wbseq_q(3) and not wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0)) or
|
||||
(not wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or
|
||||
(not wbseq_q(3) and wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or
|
||||
(wbseq_q(3) and not wbseq_q(2) and wbseq_q(1) and wbseq_q(0)) or
|
||||
(wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and not wbseq_q(0)) or
|
||||
(wbseq_q(3) and wbseq_q(2) and not wbseq_q(1) and wbseq_q(0));
|
||||
--vtable WBSlaveSeq
|
||||
|
||||
--vtable SendSeq
|
||||
oseq_d(3) <=
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and oseq_hold) or
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not wb_remote_rd and not wb_remote_wr) or
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not oseq_hold and not oclk_advance) or
|
||||
(not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and not wb_remote_wr and oclk_advance and oaddr_last) or
|
||||
(not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and oclk_advance and odata_last) or
|
||||
(oseq_q(3) and not oseq_q(2) and not oseq_q(1) and not oseq_q(0)) or
|
||||
(oseq_q(3) and not oseq_q(2) and not oseq_q(1) and oseq_q(0)) or
|
||||
(oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0)) or
|
||||
(oseq_q(3) and not oseq_q(2) and oseq_q(1) and oseq_q(0)) or
|
||||
(oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0)) or
|
||||
(oseq_q(3) and oseq_q(2) and not oseq_q(1) and oseq_q(0)) or
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and not oseq_q(0));
|
||||
oseq_d(2) <=
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and oseq_hold) or
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not wb_remote_rd and not wb_remote_wr) or
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not oseq_hold and not oclk_advance) or
|
||||
(not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and not wb_remote_wr and oclk_advance and oaddr_last) or
|
||||
(not oseq_q(3) and not oseq_q(2) and oseq_q(1) and oseq_q(0) and oclk_advance) or
|
||||
(not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and not oclk_advance) or
|
||||
(not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and oclk_advance and not odata_last) or
|
||||
(not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and oclk_advance and odata_last) or
|
||||
(not oseq_q(3) and oseq_q(2) and not oseq_q(1) and oseq_q(0)) or
|
||||
(not oseq_q(3) and oseq_q(2) and oseq_q(1) and not oseq_q(0)) or
|
||||
(not oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0)) or
|
||||
(oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0)) or
|
||||
(oseq_q(3) and oseq_q(2) and not oseq_q(1) and oseq_q(0)) or
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and not oseq_q(0));
|
||||
oseq_d(1) <=
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and oseq_hold) or
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not wb_remote_rd and not wb_remote_wr) or
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not oseq_hold and not oclk_advance) or
|
||||
(not oseq_q(3) and not oseq_q(2) and not oseq_q(1) and oseq_q(0) and wb_remote_rd and oclk_advance) or
|
||||
(not oseq_q(3) and not oseq_q(2) and not oseq_q(1) and oseq_q(0) and wb_remote_wr and oclk_advance) or
|
||||
(not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and not oclk_advance) or
|
||||
(not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and oclk_advance and not oaddr_last) or
|
||||
(not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and not wb_remote_wr and oclk_advance and oaddr_last) or
|
||||
(not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and wb_remote_wr and oclk_advance and oaddr_last) or
|
||||
(not oseq_q(3) and not oseq_q(2) and oseq_q(1) and oseq_q(0) and not oclk_advance) or
|
||||
(not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and oclk_advance and odata_last) or
|
||||
(not oseq_q(3) and oseq_q(2) and oseq_q(1) and not oseq_q(0)) or
|
||||
(not oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0)) or
|
||||
(oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0)) or
|
||||
(oseq_q(3) and not oseq_q(2) and oseq_q(1) and oseq_q(0)) or
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and not oseq_q(0));
|
||||
oseq_d(0) <=
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and oseq_hold) or
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not wb_remote_rd and not wb_remote_wr) or
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not oseq_hold and not oclk_advance) or
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not oseq_hold and wb_remote_rd and oclk_advance) or
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not oseq_hold and wb_remote_wr and oclk_advance) or
|
||||
(not oseq_q(3) and not oseq_q(2) and not oseq_q(1) and oseq_q(0) and not oclk_advance) or
|
||||
(not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and not wb_remote_wr and oclk_advance and oaddr_last) or
|
||||
(not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and wb_remote_wr and oclk_advance and oaddr_last) or
|
||||
(not oseq_q(3) and not oseq_q(2) and oseq_q(1) and oseq_q(0) and not oclk_advance) or
|
||||
(not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and oclk_advance and odata_last) or
|
||||
(not oseq_q(3) and oseq_q(2) and not oseq_q(1) and oseq_q(0)) or
|
||||
(not oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0)) or
|
||||
(oseq_q(3) and not oseq_q(2) and not oseq_q(1) and oseq_q(0)) or
|
||||
(oseq_q(3) and not oseq_q(2) and oseq_q(1) and oseq_q(0)) or
|
||||
(oseq_q(3) and oseq_q(2) and not oseq_q(1) and oseq_q(0));
|
||||
odata_ld_header <=
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not oseq_hold and wb_remote_rd and oclk_advance) or
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not oseq_hold and wb_remote_wr and oclk_advance);
|
||||
odata_ld_addr <=
|
||||
(not oseq_q(3) and not oseq_q(2) and not oseq_q(1) and oseq_q(0) and wb_remote_rd and oclk_advance) or
|
||||
(not oseq_q(3) and not oseq_q(2) and not oseq_q(1) and oseq_q(0) and wb_remote_wr and oclk_advance) or
|
||||
(not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and not oclk_advance) or
|
||||
(not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and oclk_advance and not oaddr_last);
|
||||
odata_ld_sel <=
|
||||
(not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and wb_remote_wr and oclk_advance and oaddr_last);
|
||||
odata_clear <=
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and oseq_hold) or
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not wb_remote_rd and not wb_remote_wr) or
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0) and not oseq_hold and not oclk_advance) or
|
||||
(not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and not wb_remote_wr and oclk_advance and oaddr_last) or
|
||||
(not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and wb_remote_wr and oclk_advance and oaddr_last);
|
||||
odata_ld_data <=
|
||||
(not oseq_q(3) and not oseq_q(2) and oseq_q(1) and oseq_q(0) and oclk_advance) or
|
||||
(not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and not oclk_advance) or
|
||||
(not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and oclk_advance and not odata_last) or
|
||||
(not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and oclk_advance and odata_last);
|
||||
ob_complete <=
|
||||
(not oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0) and not wb_remote_wr and oclk_advance and oaddr_last) or
|
||||
(not oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0) and oclk_advance and odata_last);
|
||||
oseq_err <=
|
||||
(not oseq_q(3) and not oseq_q(2) and not oseq_q(1) and not oseq_q(0)) or
|
||||
(not oseq_q(3) and oseq_q(2) and not oseq_q(1) and oseq_q(0)) or
|
||||
(not oseq_q(3) and oseq_q(2) and oseq_q(1) and not oseq_q(0)) or
|
||||
(not oseq_q(3) and oseq_q(2) and oseq_q(1) and oseq_q(0)) or
|
||||
(oseq_q(3) and not oseq_q(2) and not oseq_q(1) and not oseq_q(0)) or
|
||||
(oseq_q(3) and not oseq_q(2) and not oseq_q(1) and oseq_q(0)) or
|
||||
(oseq_q(3) and not oseq_q(2) and oseq_q(1) and not oseq_q(0)) or
|
||||
(oseq_q(3) and not oseq_q(2) and oseq_q(1) and oseq_q(0)) or
|
||||
(oseq_q(3) and oseq_q(2) and not oseq_q(1) and not oseq_q(0)) or
|
||||
(oseq_q(3) and oseq_q(2) and not oseq_q(1) and oseq_q(0)) or
|
||||
(oseq_q(3) and oseq_q(2) and oseq_q(1) and not oseq_q(0));
|
||||
--vtable SendSeq
|
||||
|
||||
--vtable RecvSeq
|
||||
iseq_d(3) <=
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and not icapture_q) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and idle_header) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and rd8_rsp) or
|
||||
(iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0) and not icapture_q) or
|
||||
(iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0) and icapture_q and not rd_rsp_data_done) or
|
||||
(iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0) and icapture_q and rd_rsp_data_done) or
|
||||
(not iseq_q(3) and not iseq_q(2) and not iseq_q(1) and iseq_q(0)) or
|
||||
(not iseq_q(3) and not iseq_q(2) and iseq_q(1) and not iseq_q(0)) or
|
||||
(not iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and idle_header) or
|
||||
(iseq_q(3) and not iseq_q(2) and not iseq_q(1) and iseq_q(0)) or
|
||||
(iseq_q(3) and not iseq_q(2) and iseq_q(1) and not iseq_q(0)) or
|
||||
(iseq_q(3) and not iseq_q(2) and iseq_q(1) and iseq_q(0)) or
|
||||
(iseq_q(3) and iseq_q(2) and not iseq_q(1) and not iseq_q(0)) or
|
||||
(iseq_q(3) and iseq_q(2) and not iseq_q(1) and iseq_q(0)) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and not iseq_q(0));
|
||||
iseq_d(2) <=
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and not icapture_q) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and idle_header) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and bad_header) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and sync_ack) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and cache_inv) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and link_req_i) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and link_rsp_i) or
|
||||
(iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0) and icapture_q and rd_rsp_data_done) or
|
||||
(not iseq_q(3) and not iseq_q(2) and not iseq_q(1) and iseq_q(0)) or
|
||||
(not iseq_q(3) and not iseq_q(2) and iseq_q(1) and not iseq_q(0)) or
|
||||
(not iseq_q(3) and iseq_q(2) and iseq_q(1) and not iseq_q(0)) or
|
||||
(not iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and not icapture_q) or
|
||||
(not iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and idle_header) or
|
||||
(not iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and not idle_header) or
|
||||
(not iseq_q(3) and iseq_q(2) and not iseq_q(1) and not iseq_q(0)) or
|
||||
(not iseq_q(3) and iseq_q(2) and not iseq_q(1) and iseq_q(0)) or
|
||||
(iseq_q(3) and iseq_q(2) and not iseq_q(1) and not iseq_q(0)) or
|
||||
(iseq_q(3) and iseq_q(2) and not iseq_q(1) and iseq_q(0)) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and not iseq_q(0));
|
||||
iseq_d(1) <=
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and not icapture_q) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and idle_header) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and bad_header) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and int_req) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and sync_ack) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and cache_inv) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and link_req_i) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and link_rsp_i) or
|
||||
(iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0) and icapture_q and rd_rsp_data_done) or
|
||||
(not iseq_q(3) and not iseq_q(2) and not iseq_q(1) and iseq_q(0)) or
|
||||
(not iseq_q(3) and not iseq_q(2) and iseq_q(1) and not iseq_q(0)) or
|
||||
(not iseq_q(3) and iseq_q(2) and iseq_q(1) and not iseq_q(0)) or
|
||||
(not iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and not icapture_q) or
|
||||
(not iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and idle_header) or
|
||||
(not iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and not idle_header) or
|
||||
(not iseq_q(3) and not iseq_q(2) and iseq_q(1) and iseq_q(0)) or
|
||||
(iseq_q(3) and not iseq_q(2) and iseq_q(1) and not iseq_q(0)) or
|
||||
(iseq_q(3) and not iseq_q(2) and iseq_q(1) and iseq_q(0)) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and not iseq_q(0));
|
||||
iseq_d(0) <=
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and not icapture_q) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and idle_header) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and wr8_rsp) or
|
||||
(iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0) and icapture_q and rd_rsp_data_done) or
|
||||
(not iseq_q(3) and not iseq_q(2) and not iseq_q(1) and iseq_q(0)) or
|
||||
(not iseq_q(3) and not iseq_q(2) and iseq_q(1) and not iseq_q(0)) or
|
||||
(not iseq_q(3) and iseq_q(2) and iseq_q(1) and not iseq_q(0)) or
|
||||
(not iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and idle_header) or
|
||||
(not iseq_q(3) and not iseq_q(2) and iseq_q(1) and iseq_q(0)) or
|
||||
(not iseq_q(3) and iseq_q(2) and not iseq_q(1) and iseq_q(0)) or
|
||||
(iseq_q(3) and not iseq_q(2) and not iseq_q(1) and iseq_q(0)) or
|
||||
(iseq_q(3) and not iseq_q(2) and iseq_q(1) and iseq_q(0)) or
|
||||
(iseq_q(3) and iseq_q(2) and not iseq_q(1) and iseq_q(0));
|
||||
ld_rd_data <=
|
||||
(iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0) and icapture_q and not rd_rsp_data_done) or
|
||||
(iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0) and icapture_q and rd_rsp_data_done);
|
||||
rd_rsp_complete <=
|
||||
(iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0) and icapture_q and rd_rsp_data_done);
|
||||
wr_rsp_complete <=
|
||||
(not iseq_q(3) and not iseq_q(2) and not iseq_q(1) and iseq_q(0));
|
||||
int_req_complete <=
|
||||
(not iseq_q(3) and not iseq_q(2) and iseq_q(1) and not iseq_q(0));
|
||||
idata_clear <=
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and not icapture_q) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0) and icapture_q and idle_header);
|
||||
save_header <=
|
||||
(not iseq_q(3) and not iseq_q(2) and iseq_q(1) and not iseq_q(0)) or
|
||||
(not iseq_q(3) and iseq_q(2) and iseq_q(1) and not iseq_q(0));
|
||||
iseq_idle <=
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and iseq_q(0));
|
||||
iseq_err <=
|
||||
(not iseq_q(3) and not iseq_q(2) and not iseq_q(1) and not iseq_q(0)) or
|
||||
(not iseq_q(3) and not iseq_q(2) and iseq_q(1) and iseq_q(0)) or
|
||||
(not iseq_q(3) and iseq_q(2) and not iseq_q(1) and not iseq_q(0)) or
|
||||
(not iseq_q(3) and iseq_q(2) and not iseq_q(1) and iseq_q(0)) or
|
||||
(iseq_q(3) and not iseq_q(2) and not iseq_q(1) and iseq_q(0)) or
|
||||
(iseq_q(3) and not iseq_q(2) and iseq_q(1) and not iseq_q(0)) or
|
||||
(iseq_q(3) and not iseq_q(2) and iseq_q(1) and iseq_q(0)) or
|
||||
(iseq_q(3) and iseq_q(2) and not iseq_q(1) and not iseq_q(0)) or
|
||||
(iseq_q(3) and iseq_q(2) and not iseq_q(1) and iseq_q(0)) or
|
||||
(iseq_q(3) and iseq_q(2) and iseq_q(1) and not iseq_q(0));
|
||||
--vtable RecvSeq
|
||||
|
||||
end architecture mc;
|
@ -0,0 +1,186 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
package mc_pkg is
|
||||
|
||||
constant BAR_BITS : integer := 16;
|
||||
|
||||
--types
|
||||
type T_Config is record
|
||||
oib_en : std_ulogic;
|
||||
oib_ratio : std_ulogic_vector(3 downto 0);
|
||||
oib_width : std_ulogic_vector(2 downto 0);
|
||||
cpol : std_ulogic;
|
||||
cpha : std_ulogic;
|
||||
ib_en_pck : std_ulogic;
|
||||
rsvd0 : std_ulogic_vector(2 downto 0);
|
||||
bar_en : std_ulogic;
|
||||
int_req : std_ulogic;
|
||||
bar : std_ulogic_vector(BAR_BITS-1 downto 0);
|
||||
--bar mask
|
||||
rsvd1 : std_ulogic_vector(7 downto 0);
|
||||
idle_flit : std_ulogic_vector(7 downto 0);
|
||||
rcv_header : std_ulogic_vector(7 downto 0);
|
||||
err : std_ulogic_vector(7 downto 0);
|
||||
end record;
|
||||
|
||||
-- functions
|
||||
function inc(a: in std_ulogic_vector) return std_ulogic_vector;
|
||||
function inc(a: in std_ulogic_vector; b: in integer) return std_ulogic_vector;use ieee.numeric_std.all;
|
||||
function dec(a: in std_ulogic_vector) return std_ulogic_vector;
|
||||
function eq(a: in std_ulogic_vector; b: in integer) return boolean;
|
||||
function eq(a: in std_ulogic_vector; b: in integer) return std_ulogic;
|
||||
function eq(a: in std_ulogic_vector; b: in std_ulogic_vector) return boolean;
|
||||
function eq(a: in std_ulogic_vector; b: in std_ulogic_vector) return std_ulogic;
|
||||
|
||||
function gate_and(a: in std_ulogic; b: in std_ulogic_vector) return std_ulogic_vector;
|
||||
function or_reduce(slv: in std_ulogic_vector) return std_ulogic;
|
||||
function and_reduce(slv: in std_ulogic_vector) return std_ulogic;
|
||||
|
||||
function clog2(n : in integer) return integer;
|
||||
|
||||
function bus_ratio_enc(n : in integer) return std_ulogic_vector;
|
||||
function bus_width_enc(n : in integer) return std_ulogic_vector;
|
||||
|
||||
end package mc_pkg;
|
||||
|
||||
|
||||
package body mc_pkg is
|
||||
|
||||
function inc(a: in std_ulogic_vector) return std_ulogic_vector is
|
||||
variable res: std_ulogic_vector(0 to a'length-1);
|
||||
begin
|
||||
res := std_ulogic_vector(unsigned(a) + 1);
|
||||
return res;
|
||||
end function;
|
||||
|
||||
function inc(a: in std_ulogic_vector; b: in integer) return std_ulogic_vector is
|
||||
variable res: std_ulogic_vector(0 to a'length-1);
|
||||
begin
|
||||
res := std_ulogic_vector(unsigned(a) + b);
|
||||
return res;
|
||||
end function;
|
||||
|
||||
function dec(a: in std_ulogic_vector) return std_ulogic_vector is
|
||||
variable res: std_ulogic_vector(0 to a'length-1);
|
||||
begin
|
||||
res := std_ulogic_vector(unsigned(a) - 1);
|
||||
return res;
|
||||
end function;
|
||||
|
||||
function eq(a: in std_ulogic_vector; b: in integer) return boolean is
|
||||
variable res: boolean;
|
||||
begin
|
||||
res := unsigned(a) = b;
|
||||
return res;
|
||||
end function;
|
||||
|
||||
function eq(a: in std_ulogic_vector; b: in integer) return std_ulogic is
|
||||
variable res: std_ulogic;
|
||||
begin
|
||||
if unsigned(a) = b then
|
||||
res := '1';
|
||||
else
|
||||
res := '0';
|
||||
end if;
|
||||
return res;
|
||||
end function;
|
||||
|
||||
function eq(a: in std_ulogic_vector; b: in std_ulogic_vector) return boolean is
|
||||
variable res: boolean;
|
||||
begin
|
||||
res := unsigned(a) = unsigned(b);
|
||||
return res;
|
||||
end function;
|
||||
|
||||
function eq(a: in std_ulogic_vector; b: in std_ulogic_vector) return std_ulogic is
|
||||
variable res: std_ulogic;
|
||||
begin
|
||||
if unsigned(a) = unsigned(b) then
|
||||
res := '1';
|
||||
else
|
||||
res := '0';
|
||||
end if;
|
||||
return res;
|
||||
end function;
|
||||
|
||||
function gate_and(a: in std_ulogic; b: in std_ulogic_vector) return std_ulogic_vector is
|
||||
variable res: std_ulogic_vector(0 to b'length-1);
|
||||
begin
|
||||
if a = '1' then
|
||||
res := b;
|
||||
else
|
||||
res := (others => '0');
|
||||
end if;
|
||||
return res;
|
||||
end function;
|
||||
|
||||
function or_reduce(slv: in std_ulogic_vector) return std_ulogic is
|
||||
variable res: std_logic := '0';
|
||||
begin
|
||||
for i in 0 to slv'length-1 loop
|
||||
res := res or slv(i);
|
||||
end loop;
|
||||
return res;
|
||||
end function;
|
||||
|
||||
function and_reduce(slv: in std_ulogic_vector) return std_ulogic is
|
||||
variable res: std_logic := '1';
|
||||
begin
|
||||
for i in 0 to slv'length-1 loop
|
||||
res := res and slv(i);
|
||||
end loop;
|
||||
return res;
|
||||
end function;
|
||||
|
||||
function clog2(n : in integer) return integer is
|
||||
variable i : integer;
|
||||
variable j : integer := n - 1;
|
||||
variable res : integer := 1;
|
||||
begin
|
||||
for i in 0 to 31 loop
|
||||
if (j > 1) then
|
||||
j := j / 2;
|
||||
res := res + 1;
|
||||
else
|
||||
exit;
|
||||
end if;
|
||||
end loop;
|
||||
return res;
|
||||
end;
|
||||
|
||||
function bus_ratio_enc(n : in integer) return std_ulogic_vector is
|
||||
variable res : std_ulogic_vector(3 downto 0);
|
||||
begin
|
||||
case n is
|
||||
when 1 => res := "0000";
|
||||
when 2 => res := "0001";
|
||||
when 4 => res := "0010";
|
||||
when 8 => res := "0011";
|
||||
when 16 => res := "0100";
|
||||
when 32 => res := "0101";
|
||||
when 64 => res := "0110";
|
||||
when 128 => res := "0111";
|
||||
when 256 => res := "1000";
|
||||
when 512 => res := "1001";
|
||||
when others => res := "1111";
|
||||
end case;
|
||||
return res;
|
||||
end;
|
||||
|
||||
function bus_width_enc(n : in integer) return std_ulogic_vector is
|
||||
variable res : std_ulogic_vector(2 downto 0);
|
||||
begin
|
||||
case n is
|
||||
when 1 => res := "000";
|
||||
when 2 => res := "001";
|
||||
when 4 => res := "010";
|
||||
when 8 => res := "011";
|
||||
when 16 => res := "100";
|
||||
when others => res := "111";
|
||||
end case;
|
||||
return res;
|
||||
end;
|
||||
|
||||
end package body mc_pkg;
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,337 @@
|
||||
00000000
|
||||
00000000
|
||||
48000024
|
||||
01006b69
|
||||
a602487d
|
||||
a64b5a7d
|
||||
2402004c
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
48000024
|
||||
01006b69
|
||||
a602487d
|
||||
a64b5a7d
|
||||
2402004c
|
||||
3c200000
|
||||
782107c6
|
||||
60211f00
|
||||
618c0000
|
||||
658c0000
|
||||
7d8903a6
|
||||
48000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
e8010010
|
||||
7c0803a6
|
||||
3c400001
|
||||
7c0802a6
|
||||
f8010010
|
||||
480001ed
|
||||
60000000
|
||||
48000155
|
||||
48000049
|
||||
7c7f1b78
|
||||
57ff063e
|
||||
60000000
|
||||
4082ffe0
|
||||
480000a5
|
||||
4bffffd0
|
||||
01000000
|
||||
3c400001
|
||||
60000000
|
||||
60000000
|
||||
2c090000
|
||||
e92a0000
|
||||
7c0004ac
|
||||
71290001
|
||||
e86a0000
|
||||
7c601eaa
|
||||
4e800020
|
||||
39290010
|
||||
7d204eea
|
||||
4082ffec
|
||||
38630008
|
||||
7c601eea
|
||||
00000000
|
||||
00000000
|
||||
38428a00
|
||||
89228090
|
||||
39428088
|
||||
4182002c
|
||||
39290014
|
||||
7d204eaa
|
||||
4182ffec
|
||||
7c0004ac
|
||||
4e800020
|
||||
39290010
|
||||
7d204eea
|
||||
4082ffec
|
||||
e94a0000
|
||||
7d2057ea
|
||||
00000000
|
||||
00000000
|
||||
38428a00
|
||||
fbe1fff8
|
||||
3be3ffff
|
||||
f821ffd1
|
||||
2c3e0000
|
||||
38210030
|
||||
4bfffe44
|
||||
4082000c
|
||||
4bffff45
|
||||
4bffff3d
|
||||
00000000
|
||||
00000280
|
||||
38600000
|
||||
2c0a0000
|
||||
38630001
|
||||
00000000
|
||||
00000000
|
||||
38428a00
|
||||
614a0020
|
||||
7c0004ac
|
||||
3d20c000
|
||||
61290008
|
||||
7c0004ac
|
||||
71290020
|
||||
3d20c000
|
||||
79290020
|
||||
7d204eea
|
||||
3d00c000
|
||||
61082000
|
||||
60000000
|
||||
3d00001c
|
||||
7d4a4392
|
||||
60000000
|
||||
99228090
|
||||
6108200c
|
||||
79080020
|
||||
7d2047aa
|
||||
7c0004ac
|
||||
e9228088
|
||||
39290004
|
||||
7d404faa
|
||||
39400003
|
||||
7c0004ac
|
||||
e9228088
|
||||
7c0004ac
|
||||
e9228088
|
||||
39290008
|
||||
7d404faa
|
||||
60000000
|
||||
99228090
|
||||
61292018
|
||||
7c0004ac
|
||||
4e800020
|
||||
00000000
|
||||
3c400001
|
||||
60000000
|
||||
2c240000
|
||||
60000000
|
||||
419e0030
|
||||
39400002
|
||||
41820008
|
||||
39290004
|
||||
7d404faa
|
||||
39400000
|
||||
41820008
|
||||
39290020
|
||||
7c604fea
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
01417804
|
||||
00000018
|
||||
fffffc48
|
||||
300e4600
|
||||
00000001
|
||||
00000000
|
||||
01417804
|
||||
00000010
|
||||
fffffc88
|
||||
00000000
|
||||
0000002c
|
||||
00000080
|
||||
00000028
|
||||
fffffd64
|
||||
41094500
|
||||
300e4302
|
||||
42000e0a
|
||||
0000000b
|
||||
0000006c
|
||||
00000028
|
||||
00000010
|
||||
fffffdac
|
||||
00000000
|
||||
00000094
|
||||
00000074
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
00000000
|
||||
4f4f6f2e
|
||||
0a202020
|
||||
20202020
|
||||
203b200a
|
||||
3b20202e
|
||||
6f726369
|
||||
7469202c
|
||||
0a2e736b
|
||||
27202027
|
||||
200a2020
|
||||
2f207c7c
|
||||
2020200a
|
||||
2020203b
|
||||
20202020
|
||||
20202020
|
||||
60202020
|
||||
000a2020
|
@ -0,0 +1,24 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
import struct
|
||||
|
||||
even = open('even.hex', 'w')
|
||||
odd = open('odd.hex', 'w')
|
||||
|
||||
with open(sys.argv[1], "rb") as f:
|
||||
while True:
|
||||
even_word = f.read(4)
|
||||
if len(even_word) == 0:
|
||||
exit(0)
|
||||
if len(even_word) != 4:
|
||||
raise Exception("Bad length")
|
||||
even.write("%08x\n" % struct.unpack('<I', even_word));
|
||||
|
||||
odd_word = f.read(4)
|
||||
if len(odd_word) == 0:
|
||||
exit(0)
|
||||
if len(odd_word) != 4:
|
||||
raise Exception("Bad length")
|
||||
odd.write("%08x\n" % struct.unpack('<I', odd_word));
|
@ -0,0 +1,196 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <poll.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
/* XXX Make that some parameter */
|
||||
#define TCP_PORT 13245
|
||||
|
||||
static int fd = -1;
|
||||
static int cfd = -1;
|
||||
|
||||
static void open_socket(void)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
int opt, rc, flags;
|
||||
|
||||
if (fd >= 0 || fd < -1)
|
||||
return;
|
||||
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
fd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Failed to open debug socket\r\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
flags = fcntl(fd, F_GETFL);
|
||||
if (flags >= 0)
|
||||
rc = fcntl(fd, F_SETFL, flags | O_NONBLOCK);
|
||||
if (flags < 0 || rc < 0) {
|
||||
fprintf(stderr, "Failed to configure debug socket\r\n");
|
||||
}
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(TCP_PORT);
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
opt = 1;
|
||||
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
||||
rc = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Failed to bind debug socket\r\n");
|
||||
goto fail;
|
||||
}
|
||||
rc = listen(fd,1);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "Failed to listen to debug socket\r\n");
|
||||
goto fail;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
fprintf(stdout, "Debug socket ready\r\n");
|
||||
#endif
|
||||
return;
|
||||
fail:
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
fd = -2;
|
||||
}
|
||||
|
||||
static void check_connection(void)
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
|
||||
cfd = accept(fd, (struct sockaddr *)&addr, &addr_len);
|
||||
if (cfd < 0)
|
||||
return;
|
||||
#ifdef DEBUG
|
||||
fprintf(stdout, "Debug client connected\r\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool read_one_byte(char *c)
|
||||
{
|
||||
struct pollfd fdset[1];
|
||||
int rc;
|
||||
|
||||
if (fd == -1)
|
||||
open_socket();
|
||||
if (fd < 0)
|
||||
return false;
|
||||
if (cfd < 0)
|
||||
check_connection();
|
||||
if (cfd < 0)
|
||||
return false;
|
||||
|
||||
memset(fdset, 0, sizeof(fdset));
|
||||
fdset[0].fd = cfd;
|
||||
fdset[0].events = POLLIN;
|
||||
rc = poll(fdset, 1, 0);
|
||||
if (rc <= 0)
|
||||
return false;
|
||||
rc = read(cfd, c, 1);
|
||||
if (rc != 1) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stdout, "Debug read error, assuming client disconnected !\r\n");
|
||||
#endif
|
||||
close(cfd);
|
||||
cfd = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stdout, "Got message: %c\n", *c);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void write_one_byte(char c)
|
||||
{
|
||||
int rc;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stdout, "Sending message: %c\r\n", c);
|
||||
#endif
|
||||
|
||||
rc = write(cfd, &c, 1);
|
||||
if (rc != 1) {
|
||||
#ifdef DEBUG
|
||||
fprintf(stdout, "JTAG write error, disconnecting\r\n");
|
||||
#endif
|
||||
close(cfd);
|
||||
cfd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
struct jtag_in {
|
||||
uint8_t tck;
|
||||
uint8_t tms;
|
||||
uint8_t tdi;
|
||||
uint8_t trst;
|
||||
};
|
||||
|
||||
static struct jtag_in jtag_in;
|
||||
|
||||
struct jtag_in jtag_one_cycle(uint8_t tdo)
|
||||
{
|
||||
char c;
|
||||
|
||||
if (read_one_byte(&c) == false)
|
||||
goto out;
|
||||
|
||||
// Write request
|
||||
if ((c >= '0') && (c <= '7')) {
|
||||
uint8_t val = c - '0';
|
||||
|
||||
jtag_in.tck = (val >> 2) & 1;
|
||||
jtag_in.tms = (val >> 1) & 1;
|
||||
jtag_in.tdi = (val >> 0) & 1;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
// Reset request
|
||||
if ((c >= 'r') && (c <= 'u')) {
|
||||
uint8_t val = c - 'r';
|
||||
|
||||
jtag_in.trst = (val >> 1) & 1;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case 'B': // Blink on
|
||||
case 'b': // Blink off
|
||||
goto out;
|
||||
|
||||
case 'R': // Read request
|
||||
write_one_byte(tdo + '0');
|
||||
goto out;
|
||||
|
||||
case 'Q': // Quit request
|
||||
#ifdef DEBUG
|
||||
fprintf(stdout, "Disconnecting JTAG\r\n");
|
||||
#endif
|
||||
close(cfd);
|
||||
cfd = -1;
|
||||
goto out;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "Unknown JTAG command %c\r\n", c);
|
||||
}
|
||||
|
||||
out:
|
||||
return jtag_in;
|
||||
}
|
Loading…
Reference in New Issue