Compare commits

...

24 Commits

Author SHA1 Message Date
Anton Blanchard f3f159c6dc Check in verilog 3 years ago
Anton Blanchard 4a7844404e Forgot to add DFFRAM 3 years ago
Anton Blanchard 6f697e4f5f Update PVR
Set a unique PVR for the caravel version of microwatt
3 years ago
Anton Blanchard 9910d99320 Not sure we need this 3 years ago
Anton Blanchard 9ccf9a7f80 Add a script to post process the microwatt verilog for caravel 3 years ago
Jordan Niethe a45c503aea Connect to the caravel logic analyzer
This connects 32 read and 32 write bits to the caravel logic analyzer.

Thanks to Jordan for the original patch
3 years ago
Anton Blanchard ce27cd3e28 Disable debug log 3 years ago
Anton Blanchard 5326455c02 No need to set HAS_FPU and LOG_LENGTH in Makefile 3 years ago
Anton Blanchard bf0c08dd87 tie off wb_ext_io_out 3 years ago
Anton Blanchard 120e1ce6ec SPI fixes, and remove reset controller and PLL
We need to expose all the input, output and output enable SPI lines
in order to use QSPI.

Remove the reset controller and PLL, since we are driving these
directly from caravel.
3 years ago
Michael Neuling 0664747146 Set alt reset vector to the start of flash at 0xf0000000 and make it
programmable externally (using carvel LA)
3 years ago
Michael Neuling 4685ff6bbb Add mc*.vhdl from:
git@github.com:openpowerwtf/uw_fab.git
3 years ago
Anton Blanchard 185bcba6bb Add a simple test case
We use 2 32bit RAMs, so we need to split the test case into
two files.
3 years ago
Anton Blanchard 83faae4a86 Add RAM_512x64 3 years ago
Anton Blanchard d1f0ac2e0b Disable second uart since we aren't using it 3 years ago
Anton Blanchard 17d93d504a Add a toplevel file for caravel 3 years ago
Anton Blanchard 9877db9b97 Disable BOOT_CLOCKS in flash controller 3 years ago
Anton Blanchard d852dedfe4 Reduce the core size
- 256B 2 way icache and dcache
- 2 entry 2 way dTLB
- 4 entry direct mapped iTLB
- 8 entry debug log
- disable FPU
3 years ago
Anton Blanchard 7fdbb7c850 Cut down hello_world to fit in 4kB 3 years ago
Michael Neuling 1ee4995cd8 Cleanup some 'U' state issues
Signed-off-by: Michael Neuling <mikey@neuling.org>
3 years ago
Anton Blanchard 55b6f8be52 Work around ghdl/yosys issue with direct mapped TLB
Workaround from Tristan.

Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
3 years ago
Anton Blanchard 0be86c3a32 Update JTAG TAP controller for Microwatt
Make a few changes to match what mw_debug expects:

- 6 byte instructions
- IDCODE at 001001
- microwatt debug at 000011

Also change IDCODE to be an IBM ID.

Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
3 years ago
Anton Blanchard 5e8ba5acb0 First pass at an external JTAG port
The verilator simulation interface uses the remote_bitbang
protocol from openocd. I have a simple implementation for
urjtag too.

Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
3 years ago
Anton Blanchard a3b70ab01e Reset cmd_ready_o in spi_txrx
Initialize bit_count so that cmd_ready_o isn't X state immediately
after reset.

Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
3 years ago

@ -52,7 +52,7 @@ core_files = decode_types.vhdl common.vhdl wishbone_types.vhdl fetch1.vhdl \

soc_files = $(core_files) wishbone_arbiter.vhdl wishbone_bram_wrapper.vhdl sync_fifo.vhdl \
wishbone_debug_master.vhdl xics.vhdl syscon.vhdl soc.vhdl \
spi_rxtx.vhdl spi_flash_ctrl.vhdl
spi_rxtx.vhdl spi_flash_ctrl.vhdl logic_analyzer.vhdl

uart_files = $(wildcard uart16550/*.v)

@ -116,7 +116,7 @@ $(soc_dram_tbs):
else

VERILATOR_CFLAGS=-O3
VERILATOR_FLAGS=-O3
VERILATOR_FLAGS=-O3 --x-assign=1 --x-initial=1
verilated_dram: litedram/generated/sim/litedram_core.v
verilator $(VERILATOR_FLAGS) -CFLAGS $(VERILATOR_CFLAGS) -Wno-fatal --cc $< --trace
make -C obj_dir -f ../litedram/extras/sim_dram_verilate.mk VERILATOR_ROOT=$(VERILATOR_ROOT)
@ -175,7 +175,7 @@ GHDL_IMAGE_GENERICS=-gMEMORY_SIZE=$(MEMORY_SIZE) -gRAM_INIT_FILE=$(RAM_INIT_FILE

clkgen=fpga/clk_gen_ecp5.vhd
toplevel=fpga/top-generic.vhdl
dmi_dtm=dmi_dtm_dummy.vhdl
dmi_dtm=dmi_dtm_jtag.vhdl dmi_dtm_dummy.vhdl

ifeq ($(FPGA_TARGET), verilator)
RESET_LOW=true
@ -184,9 +184,18 @@ CLK_FREQUENCY=50000000
clkgen=fpga/clk_gen_bypass.vhd
endif

ifeq ($(FPGA_TARGET), caravel)
RESET_LOW=true
CLK_INPUT=50000000
CLK_FREQUENCY=50000000
clkgen=fpga/clk_gen_bypass.vhd
toplevel=fpga/top-caravel.vhdl
MEMORY_SIZE=4096
endif

fpga_files = $(core_files) $(soc_files) fpga/soc_reset.vhdl \
fpga/pp_fifo.vhd fpga/pp_soc_uart.vhd fpga/main_bram.vhdl \
nonrandom.vhdl
fpga/pp_fifo.vhd fpga/pp_soc_uart.vhd fpga/main_bram_caravel.vhdl \
nonrandom.vhdl mc.vhdl mc_pkg.vhdl

synth_files = $(core_files) $(soc_files) $(fpga_files) $(clkgen) $(toplevel) $(dmi_dtm)

@ -197,8 +206,8 @@ microwatt.v: $(synth_files) $(RAM_INIT_FILE)
$(YOSYS) -m $(GHDLSYNTH) -p "ghdl --std=08 --no-formal $(GHDL_IMAGE_GENERICS) $(GHDL_TARGET_GENERICS) $(synth_files) -e toplevel; write_verilog $@"

# Need to investigate why yosys is hitting verilator warnings, and eventually turn on -Wall
microwatt-verilator: microwatt.v verilator/microwatt-verilator.cpp verilator/uart-verilator.c
verilator -O3 -CFLAGS "-DCLK_FREQUENCY=$(CLK_FREQUENCY)" --assert --cc microwatt.v --exe verilator/microwatt-verilator.cpp verilator/uart-verilator.c -o $@ -Iuart16550 -Wno-fatal -Wno-CASEOVERLAP -Wno-UNOPTFLAT #--trace
microwatt-verilator: microwatt.v verilator/microwatt-verilator.cpp verilator/uart-verilator.c verilator/jtag-verilator.c
verilator -O3 -CFLAGS "-DCLK_FREQUENCY=$(CLK_FREQUENCY)" --assert --cc microwatt.v --exe verilator/microwatt-verilator.cpp verilator/uart-verilator.c verilator/jtag-verilator.c -o $@ -Iuart16550 -Ijtag_tap -Icaravel_bram -Wno-fatal -Wno-CASEOVERLAP -Wno-UNOPTFLAT #--trace
make -C obj_dir -f Vmicrowatt.mk
@cp -f obj_dir/microwatt-verilator microwatt-verilator


@ -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,36 @@
module DFFRAM #( parameter COLS=1, filename="")
(
CLK,
WE,
EN,
Di,
Do,
A
);
localparam A_WIDTH = 8+$clog2(COLS);

input wire CLK;
input wire [3:0] WE;
input wire EN;
input wire [31:0] Di;
output reg [31:0] Do;
input wire [(A_WIDTH - 1): 0] A;

reg [31:0] RAM[(256*COLS)-1 : 0];
always @(posedge CLK)
if(EN) begin
Do <= RAM[A];
if(WE[0]) RAM[A][ 7: 0] <= Di[7:0];
if(WE[1]) RAM[A][15:8] <= Di[15:8];
if(WE[2]) RAM[A][23:16] <= Di[23:16];
if(WE[3]) RAM[A][31:24] <= Di[31:24];
end
else
Do <= 32'b0;
initial begin
$readmemh(filename, RAM);
end

endmodule

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

@ -7,7 +7,7 @@ use work.decode_types.all;

package common is
-- Processor Version Number
constant PVR_MICROWATT : std_ulogic_vector(31 downto 0) := x"00630000";
constant PVR_MICROWATT : std_ulogic_vector(31 downto 0) := x"00630100";

-- MSR bit numbers
constant MSR_SF : integer := (63 - 0); -- Sixty-Four bit mode

@ -209,7 +209,7 @@ begin
generic map(
SIM => SIM,
LINE_SIZE => 64,
NUM_LINES => 64,
NUM_LINES => 2,
NUM_WAYS => 2,
LOG_LENGTH => LOG_LENGTH
)
@ -387,7 +387,7 @@ begin
dcache_0: entity work.dcache
generic map(
LINE_SIZE => 64,
NUM_LINES => 64,
NUM_LINES => 2,
NUM_WAYS => 2,
LOG_LENGTH => LOG_LENGTH
)

@ -27,7 +27,7 @@ entity dcache is
-- Number of ways
NUM_WAYS : positive := 4;
-- L1 DTLB entries per set
TLB_SET_SIZE : positive := 64;
TLB_SET_SIZE : positive := 2;
-- L1 DTLB number of sets
TLB_NUM_WAYS : positive := 2;
-- L1 DTLB log_2(page_size)
@ -440,8 +440,12 @@ architecture rtl of dcache is
function read_tlb_tag(way: tlb_way_t; tags: tlb_way_tags_t) return tlb_tag_t is
variable j : integer;
begin
if TLB_NUM_WAYS = 1 then
return tags;
else
j := way * TLB_EA_TAG_BITS;
return tags(j + TLB_EA_TAG_BITS - 1 downto j);
end if;
end;

-- Write a TLB tag to a TLB tag memory row
@ -449,23 +453,35 @@ architecture rtl of dcache is
tag: tlb_tag_t) is
variable j : integer;
begin
if TLB_NUM_WAYS = 1 then
tags := tag;
else
j := way * TLB_EA_TAG_BITS;
tags(j + TLB_EA_TAG_BITS - 1 downto j) := tag;
end if;
end;

-- Read a PTE from a TLB PTE memory row
function read_tlb_pte(way: tlb_way_t; ptes: tlb_way_ptes_t) return tlb_pte_t is
variable j : integer;
begin
if TLB_NUM_WAYS = 1 then
return ptes;
else
j := way * TLB_PTE_BITS;
return ptes(j + TLB_PTE_BITS - 1 downto j);
end if;
end;

procedure write_tlb_pte(way: tlb_way_t; ptes: inout tlb_way_ptes_t; newpte: tlb_pte_t) is
variable j : integer;
begin
if TLB_NUM_WAYS = 1 then
ptes := newpte;
else
j := way * TLB_PTE_BITS;
ptes(j + TLB_PTE_BITS - 1 downto j) := newpte;
end if;
end;

begin
@ -608,15 +624,15 @@ begin
hit := '1';
end if;
end loop;
tlb_hit <= hit and r0_valid;
tlb_hit <= hit and r0_valid and r0.req.virt_mode;
tlb_hit_way <= hitway;
if tlb_hit = '1' then
pte <= read_tlb_pte(hitway, tlb_pte_way);
else
pte <= (others => '0');
end if;
valid_ra <= tlb_hit or not r0.req.virt_mode;
if r0.req.virt_mode = '1' then
valid_ra <= tlb_hit or (r0_valid and not r0.req.virt_mode);
if tlb_hit = '1' then
ra <= pte(REAL_ADDR_BITS - 1 downto TLB_LG_PGSZ) &
r0.req.addr(TLB_LG_PGSZ - 1 downto ROW_OFF_BITS) &
(ROW_OFF_BITS-1 downto 0 => '0');
@ -831,7 +847,7 @@ begin
-- work out whether we have permission for this access
-- NB we don't yet implement AMR, thus no KUAP
rc_ok <= perm_attr.reference and (r0.req.load or perm_attr.changed);
perm_ok <= (r0.req.priv_mode or not perm_attr.priv) and
perm_ok <= ((r0.req.priv_mode and r0.req.valid) or not perm_attr.priv) and
(perm_attr.wr_perm or (r0.req.load and perm_attr.rd_perm));
access_ok <= valid_ra and perm_ok and rc_ok;


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

@ -66,42 +66,3 @@ boot_entry:
mtctr %r12,
bctrl
b .

#define EXCEPTION(nr) \
.= nr ;\
b .

/* More exception stubs */
EXCEPTION(0x300)
EXCEPTION(0x380)
EXCEPTION(0x400)
EXCEPTION(0x480)
EXCEPTION(0x500)
EXCEPTION(0x600)
EXCEPTION(0x700)
EXCEPTION(0x800)
EXCEPTION(0x900)
EXCEPTION(0x980)
EXCEPTION(0xa00)
EXCEPTION(0xb00)
EXCEPTION(0xc00)
EXCEPTION(0xd00)
EXCEPTION(0xe00)
EXCEPTION(0xe20)
EXCEPTION(0xe40)
EXCEPTION(0xe60)
EXCEPTION(0xe80)
EXCEPTION(0xf00)
EXCEPTION(0xf20)
EXCEPTION(0xf40)
EXCEPTION(0xf60)
EXCEPTION(0xf80)
#if 0
EXCEPTION(0x1000)
EXCEPTION(0x1100)
EXCEPTION(0x1200)
EXCEPTION(0x1300)
EXCEPTION(0x1400)
EXCEPTION(0x1500)
EXCEPTION(0x1600)
#endif

Binary file not shown.

Binary file not shown.

@ -40,7 +40,7 @@ a64b5a7d14004a39
60211f0064210000
618c00003d800000
658c0000798c07c6
7d8903a6618c1014
7d8903a6618c0414
480000004e800421
0000000000000000
0000000000000000
@ -94,7 +94,6 @@ a64b5a7d14004a39
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
@ -110,7 +109,6 @@ a64b5a7d14004a39
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
@ -126,394 +124,12 @@ a64b5a7d14004a39
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000048000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
e8010010ebc1fff0
7c0803a6ebe1fff8
3c4000014e800020
7c0802a638429800
7c0802a638428a00
f8010010fbe1fff8
480001edf821ffd1
6000000060000000
@ -527,7 +143,7 @@ f8010010fbe1fff8
4bffffd060000000
0100000000000000
3c40000100000180
6000000038429800
6000000038428a00
6000000089228090
2c09000039428088
e92a000041820030
@ -543,7 +159,7 @@ e86a00004182ffec
7c601eea7c0004ac
000000004bffffd0
0000000000000000
384298003c400001
38428a003c400001
8922809060000000
3942808860000000
4182002c2c090000
@ -559,7 +175,7 @@ e94a00005469063e
7d2057ea7c0004ac
000000004e800020
0000000000000000
384298003c400001
38428a003c400001
fbe1fff87c0802a6
3be3fffffbc1fff0
f821ffd1f8010010
@ -576,7 +192,7 @@ f821ffd1f8010010
386300014d820020
000000004bfffff0
0000000000000000
384298003c400001
38428a003c400001
614a00203d40c000
7c0004ac794a0020
3d20c0007d4056ea
@ -614,7 +230,7 @@ e92280887d404faa
4e8000207d404fea
0000000000000000
3c40000100000000
6000000038429800
6000000038428a00
2c24000089228090
600000002f890000
419e0030e9228088
@ -702,70 +318,6 @@ fffffdac00000080
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
0000000000000000
4f4f6f2e2020200a
0a20202020202e6f
2020202020222e20

@ -5,9 +5,9 @@ SECTIONS
.head : {
KEEP(*(.head))
}
. = 0x1000;
. = 0x400;
.text : { *(.text) }
. = 0x1800;
. = 0xA00;
.data : { *(.data) }
.bss : { *(.bss) }
}

@ -43,7 +43,7 @@ entity icache is
-- Number of ways
NUM_WAYS : positive := 4;
-- L1 ITLB number of entries (direct mapped)
TLB_SIZE : positive := 64;
TLB_SIZE : positive := 4;
-- L1 ITLB log_2(page_size)
TLB_LG_PGSZ : positive := 12;
-- Number of real address bits that we store

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

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

-- External IO bus:
-- 0xc8000000: LiteDRAM control (CSRs)
-- We will put the gpios here ...
-- 0xc8020000: LiteEth CSRs (*)
-- 0xc8030000: LiteEth MMIO (*)

@ -65,7 +66,8 @@ entity soc is
LOG_LENGTH : natural := 512;
HAS_LITEETH : boolean := false;
UART0_IS_16550 : boolean := true;
HAS_UART1 : boolean := false
HAS_UART1 : boolean := false;
HAS_JTAG : boolean := false
);
port(
rst : in std_ulogic;
@ -100,6 +102,13 @@ entity soc is
spi_flash_sdat_oe : out std_ulogic_vector(SPI_FLASH_DLINES-1 downto 0);
spi_flash_sdat_i : in std_ulogic_vector(SPI_FLASH_DLINES-1 downto 0) := (others => '1');

-- JTAG signals
jtag_tck : in std_ulogic := '0';
jtag_tdi : in std_ulogic := '0';
jtag_tms : in std_ulogic := '0';
jtag_trst : in std_ulogic := '0';
jtag_tdo : out std_ulogic;

-- DRAM controller signals
alt_reset : in std_ulogic := '0'
);
@ -256,7 +265,7 @@ begin
SIM => SIM,
HAS_FPU => HAS_FPU,
DISABLE_FLATTEN => DISABLE_FLATTEN_CORE,
ALT_RESET_ADDRESS => (23 downto 0 => '0', others => '1'),
ALT_RESET_ADDRESS => (27 downto 0 => '0', others => '1'),
LOG_LENGTH => LOG_LENGTH
)
port map(
@ -308,13 +317,14 @@ begin
slave_top_intercon: process(wb_master_out, wb_bram_out, wb_dram_out, wb_io_out, dram_at_0)
type slave_top_type is (SLAVE_TOP_BRAM,
SLAVE_TOP_DRAM,
SLAVE_TOP_IO);
SLAVE_TOP_IO,
SLAVE_TOP_INVALID);
variable slave_top : slave_top_type;
variable top_decode : std_ulogic_vector(3 downto 0);
begin
-- Top-level address decoder
top_decode := wb_master_out.adr(31 downto 29) & dram_at_0;
slave_top := SLAVE_TOP_BRAM;
slave_top := SLAVE_TOP_INVALID;
if std_match(top_decode, "0000") then
slave_top := SLAVE_TOP_BRAM;
elsif std_match(top_decode, "0001") then
@ -335,6 +345,9 @@ begin
wb_io_in <= wb_master_out;
wb_io_in.cyc <= '0';
case slave_top is
when SLAVE_TOP_INVALID =>
-- We should terminate here
wb_master_in <= wishbone_slave_out_init;
when SLAVE_TOP_BRAM =>
wb_bram_in.cyc <= wb_master_out.cyc;
wb_master_in <= wb_bram_out;
@ -379,6 +392,7 @@ begin
wb_io_out.stall <= '0';
wb_sio_out.cyc <= '0';
wb_sio_out.stb <= '0';
wb_sio_out.adr <= (others => '0');
has_top := false;
has_bot := false;
else
@ -840,6 +854,30 @@ begin
end generate;

-- DMI(debug bus) <-> JTAG bridge
dmi_jtag: if HAS_JTAG generate
dtm: entity work.dmi_dtm_jtag
generic map(
ABITS => 8,
DBITS => 64
)
port map(
sys_clk => system_clk,
sys_reset => rst_dtm,
dmi_addr => dmi_addr,
dmi_din => dmi_din,
dmi_dout => dmi_dout,
dmi_req => dmi_req,
dmi_wr => dmi_wr,
dmi_ack => dmi_ack,
jtag_tck => jtag_tck,
jtag_tdi => jtag_tdi,
jtag_tms => jtag_tms,
jtag_trst => jtag_trst,
jtag_tdo => jtag_tdo
);
end generate;

dmi_xilinx: if not HAS_JTAG generate
dtm: entity work.dmi_dtm
generic map(
ABITS => 8,
@ -855,6 +893,7 @@ begin
dmi_wr => dmi_wr,
dmi_ack => dmi_ack
);
end generate;

-- DMI interconnect
dmi_intercon: process(dmi_addr, dmi_req,

@ -12,7 +12,7 @@ entity spi_flash_ctrl is
DEF_QUAD_READ : boolean := false; -- Use quad read with 8 clk dummy

-- Dummy clocks after boot
BOOT_CLOCKS : boolean := true; -- Send 8 dummy clocks after boot
BOOT_CLOCKS : boolean := false; -- Send 8 dummy clocks after boot

-- Number of data lines (1=MISO/MOSI, otherwise 2 or 4)
DATA_LINES : positive := 1

@ -258,6 +258,9 @@ begin
count_bit: process(clk)
begin
if rising_edge(clk) then
if rst = '1' then
bit_count <= (others => '0');
else
if start_cmd = '1' then
bit_count <= cmd_clks_i;
elsif state /= DATA then
@ -266,6 +269,7 @@ begin
bit_count <= std_ulogic_vector(unsigned(bit_count) - 1);
end if;
end if;
end if;
end process;

-- Shift output data

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

@ -46,6 +46,14 @@ void tick(Vmicrowatt *top)
void uart_tx(unsigned char tx);
unsigned char uart_rx(void);

struct jtag_in {
unsigned char tck;
unsigned char tms;
unsigned char tdi;
unsigned char trst;
};
struct jtag_in jtag_one_cycle(uint8_t tdo);

int main(int argc, char **argv)
{
Verilated::commandArgs(argc, argv);
@ -68,10 +76,19 @@ int main(int argc, char **argv)
top->ext_rst = 1;

while(!Verilated::gotFinish()) {
struct jtag_in p;

tick(top);

uart_tx(top->uart0_txd);
top->uart0_rxd = uart_rx();

p = jtag_one_cycle(top->jtag_tdo);

top->jtag_tck = p.tck;
top->jtag_tms = p.tms;
top->jtag_tdi = p.tdi;
top->jtag_trst = p.trst;
}

#if VM_TRACE

Loading…
Cancel
Save