forked from cores/microwatt
Compare commits
24 Commits
master
...
caravel-20
Author | SHA1 | Date |
---|---|---|
Anton Blanchard | f3f159c6dc | 4 years ago |
Anton Blanchard | 4a7844404e | 4 years ago |
Anton Blanchard | 6f697e4f5f | 4 years ago |
Anton Blanchard | 9910d99320 | 4 years ago |
Anton Blanchard | 9ccf9a7f80 | 4 years ago |
Jordan Niethe | a45c503aea | 4 years ago |
Anton Blanchard | ce27cd3e28 | 4 years ago |
Anton Blanchard | 5326455c02 | 4 years ago |
Anton Blanchard | bf0c08dd87 | 4 years ago |
Anton Blanchard | 120e1ce6ec | 4 years ago |
Michael Neuling | 0664747146 | 4 years ago |
Michael Neuling | 4685ff6bbb | 4 years ago |
Anton Blanchard | 185bcba6bb | 4 years ago |
Anton Blanchard | 83faae4a86 | 4 years ago |
Anton Blanchard | d1f0ac2e0b | 4 years ago |
Anton Blanchard | 17d93d504a | 4 years ago |
Anton Blanchard | 9877db9b97 | 4 years ago |
Anton Blanchard | d852dedfe4 | 4 years ago |
Anton Blanchard | 7fdbb7c850 | 4 years ago |
Michael Neuling | 1ee4995cd8 | 4 years ago |
Anton Blanchard | 55b6f8be52 | 4 years ago |
Anton Blanchard | 0be86c3a32 | 4 years ago |
Anton Blanchard | 5e8ba5acb0 | 4 years ago |
Anton Blanchard | a3b70ab01e | 4 years ago |
@ -0,0 +1,70 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
|
module_regex = r'[a-zA-Z0-9_\.\\]+'
|
||||||
|
|
||||||
|
# match:
|
||||||
|
# module dcache(clk, rst, d_in, m_in, wishbone_in, d_out, m_out, stall_out, wishbone_out);
|
||||||
|
module_re = re.compile(r'module\s+(' + module_regex + r')\((.*)\);')
|
||||||
|
|
||||||
|
# match:
|
||||||
|
# dcache_64_2_2_2_2_12_0 dcache_0 (
|
||||||
|
hookup_re = re.compile(r'\s+(' + module_regex + r') ' + module_regex + r'\s+\(')
|
||||||
|
|
||||||
|
header1 = """\
|
||||||
|
`ifdef USE_POWER_PINS
|
||||||
|
vdda1, vdda2, vssa1, vssa2, vccd1, vccd2, vssd1, vssd2,
|
||||||
|
`endif\
|
||||||
|
"""
|
||||||
|
|
||||||
|
header2 = """\
|
||||||
|
`ifdef USE_POWER_PINS
|
||||||
|
inout vdda1; // User area 1 3.3V supply
|
||||||
|
inout vdda2; // User area 2 3.3V supply
|
||||||
|
inout vssa1; // User area 1 analog ground
|
||||||
|
inout vssa2; // User area 2 analog ground
|
||||||
|
inout vccd1; // User area 1 1.8V supply
|
||||||
|
inout vccd2; // User area 2 1.8v supply
|
||||||
|
inout vssd1; // User area 1 digital ground
|
||||||
|
inout vssd2; // User area 2 digital ground
|
||||||
|
`endif\
|
||||||
|
"""
|
||||||
|
|
||||||
|
header3 = """\
|
||||||
|
`ifdef USE_POWER_PINS
|
||||||
|
.vdda1(vdda1), // User area 1 3.3V power
|
||||||
|
.vdda2(vdda2), // User area 2 3.3V power
|
||||||
|
.vssa1(vssa1), // User area 1 analog ground
|
||||||
|
.vssa2(vssa2), // User area 2 analog ground
|
||||||
|
.vccd1(vccd1), // User area 1 1.8V power
|
||||||
|
.vccd2(vccd2), // User area 2 1.8V power
|
||||||
|
.vssd1(vssd1), // User area 1 digital ground
|
||||||
|
.vssd2(vssd2), // User area 2 digital ground
|
||||||
|
`endif\
|
||||||
|
"""
|
||||||
|
|
||||||
|
if len(sys.argv) < 3:
|
||||||
|
print("Usage: insert_power.py verilog.v module1 module2..")
|
||||||
|
sys.exit(1);
|
||||||
|
|
||||||
|
verilog_file = sys.argv[1]
|
||||||
|
modules = sys.argv[2:]
|
||||||
|
|
||||||
|
with open(sys.argv[1]) as f:
|
||||||
|
for line in f:
|
||||||
|
m = module_re.match(line)
|
||||||
|
m2 = hookup_re.match(line)
|
||||||
|
if m and m.group(1) in modules:
|
||||||
|
module_name = m.group(1)
|
||||||
|
module_args = m.group(2)
|
||||||
|
print('module %s(' % module_name)
|
||||||
|
print(header1)
|
||||||
|
print(' %s);' % module_args)
|
||||||
|
print(header2)
|
||||||
|
elif m2 and m2.group(1) in modules:
|
||||||
|
print(line, end='')
|
||||||
|
print(header3)
|
||||||
|
else:
|
||||||
|
print(line, end='')
|
@ -0,0 +1,54 @@
|
|||||||
|
#!/bin/bash -e
|
||||||
|
|
||||||
|
# process microwatt verilog
|
||||||
|
|
||||||
|
FILE=microwatt.v
|
||||||
|
|
||||||
|
# Remove these modules that are implemented as hard macros
|
||||||
|
for module in register_file_0_1489f923c4dca729178b3e3233458550d8dddf29 dcache_64_2_2_2_2_12_0 icache_64_8_2_2_4_12_56_0_5ba93c9db0cff93f52b521d7420e43f6eda2784f cache_ram_4_64_1489f923c4dca729178b3e3233458550d8dddf29 cache_ram_4_64_3f29546453678b855931c174a97d6c0894b8f546 plru_1 multiply_4
|
||||||
|
do
|
||||||
|
sed -i "/^module $module/,/^endmodule/d" $FILE
|
||||||
|
done
|
||||||
|
|
||||||
|
# Remove the debug bus in the places we call our macros
|
||||||
|
for module in dcache_64_2_2_2_2_12_0 icache_64_8_2_2_4_12_56_0_5ba93c9db0cff93f52b521d7420e43f6eda2784f register_file_0_1489f923c4dca729178b3e3233458550d8dddf29; do
|
||||||
|
for port in dbg_gpr log_out sim_dump; do
|
||||||
|
sed -i "/ $module /,/);/{ /$port/d }" $FILE
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
# Rename these modules to match the hard macro names
|
||||||
|
sed -i 's/register_file_0_1489f923c4dca729178b3e3233458550d8dddf29/register_file/' $FILE
|
||||||
|
sed -i 's/dcache_64_2_2_2_2_12_0/dcache/' $FILE
|
||||||
|
sed -i 's/icache_64_8_2_2_4_12_56_0_5ba93c9db0cff93f52b521d7420e43f6eda2784f/icache/' $FILE
|
||||||
|
sed -i 's/toplevel/microwatt/' $FILE
|
||||||
|
|
||||||
|
# Add power to all macros, and route power in microwatt down to them
|
||||||
|
caravel/insert_power.py $FILE dcache icache register_file multiply_4 RAM_512x64 main_bram_64_10_4096_a75adb9e07879fb6c63b494abe06e3f9a6bb2ed9 soc_4096_50000000_0_0_4_0_4_0_c832069ef22b63469d396707bc38511cc2410ddb wishbone_bram_wrapper_4096_a75adb9e07879fb6c63b494abe06e3f9a6bb2ed9 microwatt core_0_602f7ae323a872754ff5ac989c2e00f60e206d8e execute1_0_0e356ba505631fbf715758bed27d503f8b260e3a > $FILE.tmp && mv $FILE.tmp $FILE
|
||||||
|
|
||||||
|
# Add defines
|
||||||
|
sed -i '1 a\
|
||||||
|
\
|
||||||
|
/* Hard macros */\
|
||||||
|
`ifdef SIM\
|
||||||
|
`include "RAM_512x64.v"\
|
||||||
|
`include "register_file.v"\
|
||||||
|
`include "icache.v"\
|
||||||
|
`include "dcache.v"\
|
||||||
|
`include "multiply_4.v"\
|
||||||
|
`endif\
|
||||||
|
\
|
||||||
|
/* JTAG */\
|
||||||
|
`include "tap_top.v"\
|
||||||
|
\
|
||||||
|
/* UART */\
|
||||||
|
`include "raminfr.v"\
|
||||||
|
`include "uart_receiver.v"\
|
||||||
|
`include "uart_rfifo.v"\
|
||||||
|
`include "uart_tfifo.v"\
|
||||||
|
`include "uart_transmitter.v"\
|
||||||
|
`include "uart_defines.v"\
|
||||||
|
`include "uart_regs.v"\
|
||||||
|
`include "uart_sync_flops.v"\
|
||||||
|
`include "uart_wb.v"\
|
||||||
|
`include "uart_top.v"' $FILE
|
@ -0,0 +1,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
|
@ -1,225 +0,0 @@
|
|||||||
LOCATE COMP "ext_clk" SITE "A9";
|
|
||||||
IOBUF PORT "ext_clk" IO_TYPE=LVCMOS33;
|
|
||||||
|
|
||||||
// LOCATE COMP "ext_rst_n" SITE "J2"; // io_13
|
|
||||||
// IOBUF PORT "ext_rst_n" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
|
||||||
|
|
||||||
// user_button as reset
|
|
||||||
LOCATE COMP "ext_rst_n" SITE "J17";
|
|
||||||
IOBUF PORT "ext_rst_n" IO_TYPE=SSTL135_I;
|
|
||||||
|
|
||||||
LOCATE COMP "usb_d_p" SITE "N1";
|
|
||||||
LOCATE COMP "usb_d_n" SITE "M2";
|
|
||||||
LOCATE COMP "usb_pullup" SITE "N2";
|
|
||||||
|
|
||||||
IOBUF PORT "usb_d_p" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "usb_d_n" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "usb_pullup" IO_TYPE=LVCMOS33;
|
|
||||||
|
|
||||||
LOCATE COMP "led0_g" SITE "M3";
|
|
||||||
LOCATE COMP "led0_r" SITE "K4";
|
|
||||||
LOCATE COMP "led0_b" SITE "J3";
|
|
||||||
|
|
||||||
IOBUF PORT "led0_g" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "led0_g" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "led0_b" IO_TYPE=LVCMOS33;
|
|
||||||
|
|
||||||
// discontinuous gpio numbers, match orangecrab litex platform
|
|
||||||
LOCATE COMP "pin_gpio_0" SITE "N17"; // tx
|
|
||||||
LOCATE COMP "pin_gpio_1" SITE "M18"; // rx
|
|
||||||
LOCATE COMP "pin_gpio_2" SITE "C10"; // sda
|
|
||||||
LOCATE COMP "pin_gpio_3" SITE "C9"; // scl
|
|
||||||
//
|
|
||||||
LOCATE COMP "pin_gpio_5" SITE "B10"; // io_5
|
|
||||||
LOCATE COMP "pin_gpio_6" SITE "B9"; // ...
|
|
||||||
//
|
|
||||||
LOCATE COMP "pin_gpio_9" SITE "C8"; //
|
|
||||||
LOCATE COMP "pin_gpio_10" SITE "B8"; //
|
|
||||||
LOCATE COMP "pin_gpio_11" SITE "A8"; //
|
|
||||||
LOCATE COMP "pin_gpio_12" SITE "H2"; //
|
|
||||||
LOCATE COMP "pin_gpio_13" SITE "J2"; // io_13
|
|
||||||
LOCATE COMP "pin_gpio_14" SITE "N15"; // miso
|
|
||||||
LOCATE COMP "pin_gpio_15" SITE "R17"; // sck
|
|
||||||
LOCATE COMP "pin_gpio_16" SITE "N16"; // mosi
|
|
||||||
|
|
||||||
LOCATE COMP "pin_io_a0" SITE "L4";
|
|
||||||
LOCATE COMP "pin_io_a1" SITE "N3";
|
|
||||||
LOCATE COMP "pin_io_a2" SITE "N4";
|
|
||||||
LOCATE COMP "pin_io_a3" SITE "H4";
|
|
||||||
LOCATE COMP "pin_io_a4" SITE "G4";
|
|
||||||
LOCATE COMP "pin_io_a5" SITE "T17";
|
|
||||||
|
|
||||||
IOBUF PORT "pin_gpio_0" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_1" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_2" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_3" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_5" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_6" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_9" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_10" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_11" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_12" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_13" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_14" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_15" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_gpio_16" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_io_a0" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_io_a1" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_io_a2" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_io_a3" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_io_a4" IO_TYPE=LVCMOS33;
|
|
||||||
IOBUF PORT "pin_io_a5" IO_TYPE=LVCMOS33;
|
|
||||||
|
|
||||||
LOCATE COMP "ddram_a[0]" SITE "C4";
|
|
||||||
LOCATE COMP "ddram_a[1]" SITE "D2";
|
|
||||||
LOCATE COMP "ddram_a[2]" SITE "D3";
|
|
||||||
LOCATE COMP "ddram_a[3]" SITE "A3";
|
|
||||||
LOCATE COMP "ddram_a[4]" SITE "A4";
|
|
||||||
LOCATE COMP "ddram_a[5]" SITE "D4";
|
|
||||||
LOCATE COMP "ddram_a[6]" SITE "C3";
|
|
||||||
LOCATE COMP "ddram_a[7]" SITE "B2";
|
|
||||||
LOCATE COMP "ddram_a[8]" SITE "B1";
|
|
||||||
LOCATE COMP "ddram_a[9]" SITE "D1";
|
|
||||||
LOCATE COMP "ddram_a[10]" SITE "A7";
|
|
||||||
LOCATE COMP "ddram_a[11]" SITE "C2";
|
|
||||||
LOCATE COMP "ddram_a[12]" SITE "B6";
|
|
||||||
LOCATE COMP "ddram_a[13]" SITE "C1";
|
|
||||||
LOCATE COMP "ddram_a[14]" SITE "A2";
|
|
||||||
LOCATE COMP "ddram_a[15]" SITE "C7";
|
|
||||||
IOBUF PORT "ddram_a[0]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[1]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[2]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[3]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[4]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[5]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[6]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[7]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[8]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[9]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[10]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[11]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[12]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[13]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[14]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_a[15]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
|
|
||||||
LOCATE COMP "ddram_ba[0]" SITE "D6";
|
|
||||||
LOCATE COMP "ddram_ba[1]" SITE "B7";
|
|
||||||
LOCATE COMP "ddram_ba[2]" SITE "A6";
|
|
||||||
LOCATE COMP "ddram_cas_n" SITE "D13";
|
|
||||||
LOCATE COMP "ddram_cs_n" SITE "A12";
|
|
||||||
LOCATE COMP "ddram_dm[0]" SITE "D16";
|
|
||||||
LOCATE COMP "ddram_dm[1]" SITE "G16";
|
|
||||||
LOCATE COMP "ddram_ras_n" SITE "C12";
|
|
||||||
LOCATE COMP "ddram_we_n" SITE "B12";
|
|
||||||
IOBUF PORT "ddram_ba[0]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_ba[1]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_ba[2]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_cas_n" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_cs_n" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_dm[0]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_dm[1]" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_ras_n" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_we_n" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
|
|
||||||
// from litex platform, termination disabled to reduce heat
|
|
||||||
LOCATE COMP "ddram_dq[0]" SITE "C17";
|
|
||||||
LOCATE COMP "ddram_dq[1]" SITE "D15";
|
|
||||||
LOCATE COMP "ddram_dq[2]" SITE "B17";
|
|
||||||
LOCATE COMP "ddram_dq[3]" SITE "C16";
|
|
||||||
LOCATE COMP "ddram_dq[4]" SITE "A15";
|
|
||||||
LOCATE COMP "ddram_dq[5]" SITE "B13";
|
|
||||||
LOCATE COMP "ddram_dq[6]" SITE "A17";
|
|
||||||
LOCATE COMP "ddram_dq[7]" SITE "A13";
|
|
||||||
LOCATE COMP "ddram_dq[8]" SITE "F17";
|
|
||||||
LOCATE COMP "ddram_dq[9]" SITE "F16";
|
|
||||||
LOCATE COMP "ddram_dq[10]" SITE "G15";
|
|
||||||
LOCATE COMP "ddram_dq[11]" SITE "F15";
|
|
||||||
LOCATE COMP "ddram_dq[12]" SITE "J16";
|
|
||||||
LOCATE COMP "ddram_dq[13]" SITE "C18";
|
|
||||||
LOCATE COMP "ddram_dq[14]" SITE "H16";
|
|
||||||
LOCATE COMP "ddram_dq[15]" SITE "F18";
|
|
||||||
IOBUF PORT "ddram_dq[0]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[1]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[2]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[3]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[4]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[5]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[6]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[7]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[8]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[9]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[10]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[11]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[12]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[13]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[14]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dq[15]" IO_TYPE=SSTL135_I SLEWRATE=FAST TERMINATION=OFF;
|
|
||||||
|
|
||||||
LOCATE COMP "ddram_dqs_n[0]" SITE "A16";
|
|
||||||
LOCATE COMP "ddram_dqs_n[1]" SITE "H17";
|
|
||||||
LOCATE COMP "ddram_dqs_p[0]" SITE "B15";
|
|
||||||
LOCATE COMP "ddram_dqs_p[1]" SITE "G18";
|
|
||||||
IOBUF PORT "ddram_dqs_n[0]" IO_TYPE=SSTL135D_I SLEWRATE=FAST DIFFRESISTOR=100 TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dqs_n[1]" IO_TYPE=SSTL135D_I SLEWRATE=FAST DIFFRESISTOR=100 TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dqs_p[0]" IO_TYPE=SSTL135D_I SLEWRATE=FAST DIFFRESISTOR=100 TERMINATION=OFF;
|
|
||||||
IOBUF PORT "ddram_dqs_p[1]" IO_TYPE=SSTL135D_I SLEWRATE=FAST DIFFRESISTOR=100 TERMINATION=OFF;
|
|
||||||
|
|
||||||
LOCATE COMP "ddram_clk_p" SITE "J18";
|
|
||||||
LOCATE COMP "ddram_clk_n" SITE "K18";
|
|
||||||
IOBUF PORT "ddram_clk_p" IO_TYPE=SSTL135D_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_clk_n" IO_TYPE=SSTL135D_I SLEWRATE=FAST;
|
|
||||||
|
|
||||||
LOCATE COMP "ddram_cke" SITE "D18";
|
|
||||||
LOCATE COMP "ddram_odt" SITE "C13";
|
|
||||||
LOCATE COMP "ddram_reset_n" SITE "L18";
|
|
||||||
IOBUF PORT "ddram_cke" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_odt" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_reset_n" IO_TYPE=SSTL135_I SLEWRATE=FAST;
|
|
||||||
|
|
||||||
LOCATE COMP "ddram_vccio[0]" SITE "K16";
|
|
||||||
LOCATE COMP "ddram_vccio[1]" SITE "D17";
|
|
||||||
LOCATE COMP "ddram_vccio[2]" SITE "K15";
|
|
||||||
LOCATE COMP "ddram_vccio[3]" SITE "K17";
|
|
||||||
LOCATE COMP "ddram_vccio[4]" SITE "B18";
|
|
||||||
LOCATE COMP "ddram_vccio[5]" SITE "C6";
|
|
||||||
LOCATE COMP "ddram_gnd[0]" SITE "L15";
|
|
||||||
LOCATE COMP "ddram_gnd[1]" SITE "L16";
|
|
||||||
IOBUF PORT "ddram_vccio[0]" IO_TYPE=SSTL135_II SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_vccio[1]" IO_TYPE=SSTL135_II SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_vccio[2]" IO_TYPE=SSTL135_II SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_vccio[3]" IO_TYPE=SSTL135_II SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_vccio[4]" IO_TYPE=SSTL135_II SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_vccio[5]" IO_TYPE=SSTL135_II SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_gnd[0]" IO_TYPE=SSTL135_II SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "ddram_gnd[1]" IO_TYPE=SSTL135_II SLEWRATE=FAST;
|
|
||||||
|
|
||||||
// We use USRMCLK instead for clk
|
|
||||||
// LOCATE COMP "spi_flash_clk" SITE "U16";
|
|
||||||
// IOBUF PORT "spi_flash_clk" IO_TYPE=LVCMOS33;
|
|
||||||
LOCATE COMP "spi_flash_cs_n" SITE "U17";
|
|
||||||
IOBUF PORT "spi_flash_cs_n" IO_TYPE=LVCMOS33;
|
|
||||||
LOCATE COMP "spi_flash_mosi" SITE "U18";
|
|
||||||
IOBUF PORT "spi_flash_mosi" IO_TYPE=LVCMOS33;
|
|
||||||
LOCATE COMP "spi_flash_miso" SITE "T18";
|
|
||||||
IOBUF PORT "spi_flash_miso" IO_TYPE=LVCMOS33;
|
|
||||||
LOCATE COMP "spi_flash_wp_n" SITE "R18";
|
|
||||||
IOBUF PORT "spi_flash_wp_n" IO_TYPE=LVCMOS33;
|
|
||||||
LOCATE COMP "spi_flash_hold_n" SITE "N18";
|
|
||||||
IOBUF PORT "spi_flash_hold_n" IO_TYPE=LVCMOS33;
|
|
||||||
|
|
||||||
LOCATE COMP "sdcard_data[0]" SITE "J1";
|
|
||||||
LOCATE COMP "sdcard_data[1]" SITE "K3";
|
|
||||||
LOCATE COMP "sdcard_data[2]" SITE "L3";
|
|
||||||
LOCATE COMP "sdcard_data[3]" SITE "M1";
|
|
||||||
LOCATE COMP "sdcard_cmd" SITE "K2";
|
|
||||||
LOCATE COMP "sdcard_clk" SITE "K1";
|
|
||||||
LOCATE COMP "sdcard_cd" SITE "L1";
|
|
||||||
|
|
||||||
IOBUF PORT "sdcard_data[0]" IO_TYPE=LVCMOS33 SLEWRATE=FAST PULLMODE=UP;
|
|
||||||
IOBUF PORT "sdcard_data[1]" IO_TYPE=LVCMOS33 SLEWRATE=FAST PULLMODE=UP;
|
|
||||||
IOBUF PORT "sdcard_data[2]" IO_TYPE=LVCMOS33 SLEWRATE=FAST PULLMODE=UP;
|
|
||||||
IOBUF PORT "sdcard_data[3]" IO_TYPE=LVCMOS33 SLEWRATE=FAST PULLMODE=UP;
|
|
||||||
IOBUF PORT "sdcard_cmd" IO_TYPE=LVCMOS33 SLEWRATE=FAST PULLMODE=UP;
|
|
||||||
IOBUF PORT "sdcard_clk" IO_TYPE=LVCMOS33 SLEWRATE=FAST;
|
|
||||||
IOBUF PORT "sdcard_cd" IO_TYPE=LVCMOS33;
|
|
@ -1,136 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.helpers.all;
|
|
||||||
|
|
||||||
entity bit_counter is
|
|
||||||
port (
|
|
||||||
clk : in std_logic;
|
|
||||||
rs : in std_ulogic_vector(63 downto 0);
|
|
||||||
count_right : in std_ulogic;
|
|
||||||
do_popcnt : in std_ulogic;
|
|
||||||
is_32bit : in std_ulogic;
|
|
||||||
datalen : in std_ulogic_vector(3 downto 0);
|
|
||||||
result : out std_ulogic_vector(63 downto 0)
|
|
||||||
);
|
|
||||||
end entity bit_counter;
|
|
||||||
|
|
||||||
architecture behaviour of bit_counter is
|
|
||||||
-- signals for count-leading/trailing-zeroes
|
|
||||||
signal inp : std_ulogic_vector(63 downto 0);
|
|
||||||
signal inp_r : std_ulogic_vector(63 downto 0);
|
|
||||||
signal sum : std_ulogic_vector(64 downto 0);
|
|
||||||
signal sum_r : std_ulogic_vector(64 downto 0);
|
|
||||||
signal onehot : std_ulogic_vector(63 downto 0);
|
|
||||||
signal edge : std_ulogic_vector(63 downto 0);
|
|
||||||
signal bitnum : std_ulogic_vector(5 downto 0);
|
|
||||||
signal cntz : std_ulogic_vector(63 downto 0);
|
|
||||||
|
|
||||||
-- signals for popcnt
|
|
||||||
signal dlen_r : std_ulogic_vector(3 downto 0);
|
|
||||||
signal pcnt_r : std_ulogic;
|
|
||||||
subtype twobit is unsigned(1 downto 0);
|
|
||||||
type twobit32 is array(0 to 31) of twobit;
|
|
||||||
signal pc2 : twobit32;
|
|
||||||
subtype threebit is unsigned(2 downto 0);
|
|
||||||
type threebit16 is array(0 to 15) of threebit;
|
|
||||||
signal pc4 : threebit16;
|
|
||||||
subtype fourbit is unsigned(3 downto 0);
|
|
||||||
type fourbit8 is array(0 to 7) of fourbit;
|
|
||||||
signal pc8 : fourbit8;
|
|
||||||
signal pc8_r : fourbit8;
|
|
||||||
subtype sixbit is unsigned(5 downto 0);
|
|
||||||
type sixbit2 is array(0 to 1) of sixbit;
|
|
||||||
signal pc32 : sixbit2;
|
|
||||||
signal popcnt : std_ulogic_vector(63 downto 0);
|
|
||||||
|
|
||||||
begin
|
|
||||||
countzero_r: process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
inp_r <= inp;
|
|
||||||
sum_r <= sum;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
countzero: process(all)
|
|
||||||
variable bitnum_e, bitnum_o : std_ulogic_vector(5 downto 0);
|
|
||||||
begin
|
|
||||||
if is_32bit = '0' then
|
|
||||||
if count_right = '0' then
|
|
||||||
inp <= bit_reverse(rs);
|
|
||||||
else
|
|
||||||
inp <= rs;
|
|
||||||
end if;
|
|
||||||
else
|
|
||||||
inp(63 downto 32) <= x"FFFFFFFF";
|
|
||||||
if count_right = '0' then
|
|
||||||
inp(31 downto 0) <= bit_reverse(rs(31 downto 0));
|
|
||||||
else
|
|
||||||
inp(31 downto 0) <= rs(31 downto 0);
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
sum <= std_ulogic_vector(unsigned('0' & not inp) + 1);
|
|
||||||
|
|
||||||
-- The following occurs after a clock edge
|
|
||||||
edge <= sum_r(63 downto 0) or inp_r;
|
|
||||||
bitnum_e := edgelocation(edge, 6);
|
|
||||||
onehot <= sum_r(63 downto 0) and inp_r;
|
|
||||||
bitnum_o := bit_number(onehot);
|
|
||||||
bitnum(5 downto 2) <= bitnum_e(5 downto 2);
|
|
||||||
bitnum(1 downto 0) <= bitnum_o(1 downto 0);
|
|
||||||
|
|
||||||
cntz <= 57x"0" & sum_r(64) & bitnum;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
popcnt_r: process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
for i in 0 to 7 loop
|
|
||||||
pc8_r(i) <= pc8(i);
|
|
||||||
end loop;
|
|
||||||
dlen_r <= datalen;
|
|
||||||
pcnt_r <= do_popcnt;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
popcnt_a: process(all)
|
|
||||||
begin
|
|
||||||
for i in 0 to 31 loop
|
|
||||||
pc2(i) <= unsigned("0" & rs(i * 2 downto i * 2)) + unsigned("0" & rs(i * 2 + 1 downto i * 2 + 1));
|
|
||||||
end loop;
|
|
||||||
for i in 0 to 15 loop
|
|
||||||
pc4(i) <= ('0' & pc2(i * 2)) + ('0' & pc2(i * 2 + 1));
|
|
||||||
end loop;
|
|
||||||
for i in 0 to 7 loop
|
|
||||||
pc8(i) <= ('0' & pc4(i * 2)) + ('0' & pc4(i * 2 + 1));
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
-- after a clock edge
|
|
||||||
for i in 0 to 1 loop
|
|
||||||
pc32(i) <= ("00" & pc8_r(i * 4)) + ("00" & pc8_r(i * 4 + 1)) +
|
|
||||||
("00" & pc8_r(i * 4 + 2)) + ("00" & pc8_r(i * 4 + 3));
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
popcnt <= (others => '0');
|
|
||||||
if dlen_r(3 downto 2) = "00" then
|
|
||||||
-- popcntb
|
|
||||||
for i in 0 to 7 loop
|
|
||||||
popcnt(i * 8 + 3 downto i * 8) <= std_ulogic_vector(pc8_r(i));
|
|
||||||
end loop;
|
|
||||||
elsif dlen_r(3) = '0' then
|
|
||||||
-- popcntw
|
|
||||||
for i in 0 to 1 loop
|
|
||||||
popcnt(i * 32 + 5 downto i * 32) <= std_ulogic_vector(pc32(i));
|
|
||||||
end loop;
|
|
||||||
else
|
|
||||||
popcnt(6 downto 0) <= std_ulogic_vector(('0' & pc32(0)) + ('0' & pc32(1)));
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
result <= cntz when pcnt_r = '0' else popcnt;
|
|
||||||
|
|
||||||
end behaviour;
|
|
@ -1,118 +0,0 @@
|
|||||||
library vunit_lib;
|
|
||||||
context vunit_lib.vunit_context;
|
|
||||||
|
|
||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.common.all;
|
|
||||||
|
|
||||||
library osvvm;
|
|
||||||
use osvvm.RandomPkg.all;
|
|
||||||
|
|
||||||
entity countbits_tb is
|
|
||||||
generic (runner_cfg : string := runner_cfg_default);
|
|
||||||
end countbits_tb;
|
|
||||||
|
|
||||||
architecture behave of countbits_tb is
|
|
||||||
constant clk_period: time := 10 ns;
|
|
||||||
signal rs: std_ulogic_vector(63 downto 0);
|
|
||||||
signal is_32bit, count_right: std_ulogic := '0';
|
|
||||||
signal res: std_ulogic_vector(63 downto 0);
|
|
||||||
signal clk: std_ulogic;
|
|
||||||
|
|
||||||
begin
|
|
||||||
bitcounter_0: entity work.bit_counter
|
|
||||||
port map (
|
|
||||||
clk => clk,
|
|
||||||
rs => rs,
|
|
||||||
result => res,
|
|
||||||
count_right => count_right,
|
|
||||||
is_32bit => is_32bit,
|
|
||||||
do_popcnt => '0',
|
|
||||||
datalen => "0000"
|
|
||||||
);
|
|
||||||
|
|
||||||
clk_process: process
|
|
||||||
begin
|
|
||||||
clk <= '0';
|
|
||||||
wait for clk_period/2;
|
|
||||||
clk <= '1';
|
|
||||||
wait for clk_period/2;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
stim_process: process
|
|
||||||
variable r: std_ulogic_vector(63 downto 0);
|
|
||||||
variable rnd : RandomPType;
|
|
||||||
begin
|
|
||||||
rnd.InitSeed(stim_process'path_name);
|
|
||||||
|
|
||||||
test_runner_setup(runner, runner_cfg);
|
|
||||||
|
|
||||||
while test_suite loop
|
|
||||||
if run("Test with input = 0") then
|
|
||||||
rs <= (others => '0');
|
|
||||||
is_32bit <= '0';
|
|
||||||
count_right <= '0';
|
|
||||||
wait for clk_period;
|
|
||||||
check_equal(res, 16#40#, result("for cntlzd"));
|
|
||||||
count_right <= '1';
|
|
||||||
wait for clk_period;
|
|
||||||
check_equal(res, 16#40#, result("for cnttzd"));
|
|
||||||
is_32bit <= '1';
|
|
||||||
count_right <= '0';
|
|
||||||
wait for clk_period;
|
|
||||||
check_equal(res, 16#20#, result("for cntlzw"));
|
|
||||||
count_right <= '1';
|
|
||||||
wait for clk_period;
|
|
||||||
check_equal(res, 16#20#, result("for cnttzw"));
|
|
||||||
|
|
||||||
elsif run("Test cntlzd/w") then
|
|
||||||
count_right <= '0';
|
|
||||||
for j in 0 to 100 loop
|
|
||||||
r := rnd.RandSlv(64);
|
|
||||||
r(63) := '1';
|
|
||||||
for i in 0 to 63 loop
|
|
||||||
rs <= r;
|
|
||||||
is_32bit <= '0';
|
|
||||||
wait for clk_period;
|
|
||||||
check_equal(res, i, result("for cntlzd " & to_hstring(rs)));
|
|
||||||
rs <= r(31 downto 0) & r(63 downto 32);
|
|
||||||
is_32bit <= '1';
|
|
||||||
wait for clk_period;
|
|
||||||
if i < 32 then
|
|
||||||
check_equal(res, i, result("for cntlzw " & to_hstring(rs)));
|
|
||||||
else
|
|
||||||
check_equal(res, 32, result("for cntlzw " & to_hstring(rs)));
|
|
||||||
end if;
|
|
||||||
r := '0' & r(63 downto 1);
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
elsif run("Test cnttzd/w") then
|
|
||||||
count_right <= '1';
|
|
||||||
for j in 0 to 100 loop
|
|
||||||
r := rnd.RandSlv(64);
|
|
||||||
r(0) := '1';
|
|
||||||
for i in 0 to 63 loop
|
|
||||||
rs <= r;
|
|
||||||
is_32bit <= '0';
|
|
||||||
wait for clk_period;
|
|
||||||
check_equal(res, i, result("for cnttzd " & to_hstring(rs)));
|
|
||||||
is_32bit <= '1';
|
|
||||||
wait for clk_period;
|
|
||||||
if i < 32 then
|
|
||||||
check_equal(res, i, result("for cnttzw " & to_hstring(rs)));
|
|
||||||
else
|
|
||||||
check_equal(res, 32, result("for cnttzw " & to_hstring(rs)));
|
|
||||||
end if;
|
|
||||||
r := r(62 downto 0) & '0';
|
|
||||||
end loop;
|
|
||||||
end loop;
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
|
|
||||||
test_runner_cleanup(runner);
|
|
||||||
end process;
|
|
||||||
end behave;
|
|
@ -0,0 +1,60 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.helpers.all;
|
||||||
|
|
||||||
|
entity zero_counter is
|
||||||
|
port (
|
||||||
|
clk : in std_logic;
|
||||||
|
rs : in std_ulogic_vector(63 downto 0);
|
||||||
|
count_right : in std_ulogic;
|
||||||
|
is_32bit : in std_ulogic;
|
||||||
|
result : out std_ulogic_vector(63 downto 0)
|
||||||
|
);
|
||||||
|
end entity zero_counter;
|
||||||
|
|
||||||
|
architecture behaviour of zero_counter is
|
||||||
|
signal inp : std_ulogic_vector(63 downto 0);
|
||||||
|
signal sum : std_ulogic_vector(64 downto 0);
|
||||||
|
signal msb_r : std_ulogic;
|
||||||
|
signal onehot : std_ulogic_vector(63 downto 0);
|
||||||
|
signal onehot_r : std_ulogic_vector(63 downto 0);
|
||||||
|
signal bitnum : std_ulogic_vector(5 downto 0);
|
||||||
|
|
||||||
|
begin
|
||||||
|
countzero_r: process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
msb_r <= sum(64);
|
||||||
|
onehot_r <= onehot;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
countzero: process(all)
|
||||||
|
begin
|
||||||
|
if is_32bit = '0' then
|
||||||
|
if count_right = '0' then
|
||||||
|
inp <= bit_reverse(rs);
|
||||||
|
else
|
||||||
|
inp <= rs;
|
||||||
|
end if;
|
||||||
|
else
|
||||||
|
inp(63 downto 32) <= x"FFFFFFFF";
|
||||||
|
if count_right = '0' then
|
||||||
|
inp(31 downto 0) <= bit_reverse(rs(31 downto 0));
|
||||||
|
else
|
||||||
|
inp(31 downto 0) <= rs(31 downto 0);
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
sum <= std_ulogic_vector(unsigned('0' & not inp) + 1);
|
||||||
|
onehot <= sum(63 downto 0) and inp;
|
||||||
|
|
||||||
|
-- The following occurs after a clock edge
|
||||||
|
bitnum <= bit_number(onehot_r);
|
||||||
|
|
||||||
|
result <= x"00000000000000" & "0" & msb_r & bitnum;
|
||||||
|
end process;
|
||||||
|
end behaviour;
|
@ -0,0 +1,114 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.common.all;
|
||||||
|
use work.glibc_random.all;
|
||||||
|
|
||||||
|
entity countzero_tb is
|
||||||
|
end countzero_tb;
|
||||||
|
|
||||||
|
architecture behave of countzero_tb is
|
||||||
|
constant clk_period: time := 10 ns;
|
||||||
|
signal rs: std_ulogic_vector(63 downto 0);
|
||||||
|
signal is_32bit, count_right: std_ulogic := '0';
|
||||||
|
signal result: std_ulogic_vector(63 downto 0);
|
||||||
|
signal randno: std_ulogic_vector(63 downto 0);
|
||||||
|
signal clk: std_ulogic;
|
||||||
|
|
||||||
|
begin
|
||||||
|
zerocounter_0: entity work.zero_counter
|
||||||
|
port map (
|
||||||
|
clk => clk,
|
||||||
|
rs => rs,
|
||||||
|
result => result,
|
||||||
|
count_right => count_right,
|
||||||
|
is_32bit => is_32bit
|
||||||
|
);
|
||||||
|
|
||||||
|
clk_process: process
|
||||||
|
begin
|
||||||
|
clk <= '0';
|
||||||
|
wait for clk_period/2;
|
||||||
|
clk <= '1';
|
||||||
|
wait for clk_period/2;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
stim_process: process
|
||||||
|
variable r: std_ulogic_vector(63 downto 0);
|
||||||
|
begin
|
||||||
|
-- test with input = 0
|
||||||
|
report "test zero input";
|
||||||
|
rs <= (others => '0');
|
||||||
|
is_32bit <= '0';
|
||||||
|
count_right <= '0';
|
||||||
|
wait for clk_period;
|
||||||
|
assert result = x"0000000000000040"
|
||||||
|
report "bad cntlzd 0 = " & to_hstring(result);
|
||||||
|
count_right <= '1';
|
||||||
|
wait for clk_period;
|
||||||
|
assert result = x"0000000000000040"
|
||||||
|
report "bad cnttzd 0 = " & to_hstring(result);
|
||||||
|
is_32bit <= '1';
|
||||||
|
count_right <= '0';
|
||||||
|
wait for clk_period;
|
||||||
|
assert result = x"0000000000000020"
|
||||||
|
report "bad cntlzw 0 = " & to_hstring(result);
|
||||||
|
count_right <= '1';
|
||||||
|
wait for clk_period;
|
||||||
|
assert result = x"0000000000000020"
|
||||||
|
report "bad cnttzw 0 = " & to_hstring(result);
|
||||||
|
|
||||||
|
report "test cntlzd/w";
|
||||||
|
count_right <= '0';
|
||||||
|
for j in 0 to 100 loop
|
||||||
|
r := pseudorand(64);
|
||||||
|
r(63) := '1';
|
||||||
|
for i in 0 to 63 loop
|
||||||
|
rs <= r;
|
||||||
|
is_32bit <= '0';
|
||||||
|
wait for clk_period;
|
||||||
|
assert to_integer(unsigned(result)) = i
|
||||||
|
report "bad cntlzd " & to_hstring(rs) & " -> " & to_hstring(result);
|
||||||
|
rs <= r(31 downto 0) & r(63 downto 32);
|
||||||
|
is_32bit <= '1';
|
||||||
|
wait for clk_period;
|
||||||
|
if i < 32 then
|
||||||
|
assert to_integer(unsigned(result)) = i
|
||||||
|
report "bad cntlzw " & to_hstring(rs) & " -> " & to_hstring(result);
|
||||||
|
else
|
||||||
|
assert to_integer(unsigned(result)) = 32
|
||||||
|
report "bad cntlzw " & to_hstring(rs) & " -> " & to_hstring(result);
|
||||||
|
end if;
|
||||||
|
r := '0' & r(63 downto 1);
|
||||||
|
end loop;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
report "test cnttzd/w";
|
||||||
|
count_right <= '1';
|
||||||
|
for j in 0 to 100 loop
|
||||||
|
r := pseudorand(64);
|
||||||
|
r(0) := '1';
|
||||||
|
for i in 0 to 63 loop
|
||||||
|
rs <= r;
|
||||||
|
is_32bit <= '0';
|
||||||
|
wait for clk_period;
|
||||||
|
assert to_integer(unsigned(result)) = i
|
||||||
|
report "bad cnttzd " & to_hstring(rs) & " -> " & to_hstring(result);
|
||||||
|
is_32bit <= '1';
|
||||||
|
wait for clk_period;
|
||||||
|
if i < 32 then
|
||||||
|
assert to_integer(unsigned(result)) = i
|
||||||
|
report "bad cnttzw " & to_hstring(rs) & " -> " & to_hstring(result);
|
||||||
|
else
|
||||||
|
assert to_integer(unsigned(result)) = 32
|
||||||
|
report "bad cnttzw " & to_hstring(rs) & " -> " & to_hstring(result);
|
||||||
|
end if;
|
||||||
|
r := r(62 downto 0) & '0';
|
||||||
|
end loop;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
std.env.finish;
|
||||||
|
end process;
|
||||||
|
end behave;
|
@ -0,0 +1,86 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
entity cr_hazard is
|
||||||
|
generic (
|
||||||
|
PIPELINE_DEPTH : natural := 1
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
clk : in std_ulogic;
|
||||||
|
busy_in : in std_ulogic;
|
||||||
|
deferred : in std_ulogic;
|
||||||
|
complete_in : in std_ulogic;
|
||||||
|
flush_in : in std_ulogic;
|
||||||
|
issuing : in std_ulogic;
|
||||||
|
|
||||||
|
cr_read_in : in std_ulogic;
|
||||||
|
cr_write_in : in std_ulogic;
|
||||||
|
bypassable : in std_ulogic;
|
||||||
|
|
||||||
|
stall_out : out std_ulogic;
|
||||||
|
use_bypass : out std_ulogic
|
||||||
|
);
|
||||||
|
end entity cr_hazard;
|
||||||
|
architecture behaviour of cr_hazard is
|
||||||
|
type pipeline_entry_type is record
|
||||||
|
valid : std_ulogic;
|
||||||
|
bypass : std_ulogic;
|
||||||
|
end record;
|
||||||
|
constant pipeline_entry_init : pipeline_entry_type := (valid => '0', bypass => '0');
|
||||||
|
|
||||||
|
type pipeline_t is array(0 to PIPELINE_DEPTH) of pipeline_entry_type;
|
||||||
|
constant pipeline_t_init : pipeline_t := (others => pipeline_entry_init);
|
||||||
|
|
||||||
|
signal r, rin : pipeline_t := pipeline_t_init;
|
||||||
|
begin
|
||||||
|
cr_hazard0: process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
r <= rin;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
cr_hazard1: process(all)
|
||||||
|
variable v : pipeline_t;
|
||||||
|
begin
|
||||||
|
v := r;
|
||||||
|
|
||||||
|
-- XXX assumes PIPELINE_DEPTH = 1
|
||||||
|
if complete_in = '1' then
|
||||||
|
v(1).valid := '0';
|
||||||
|
end if;
|
||||||
|
|
||||||
|
use_bypass <= '0';
|
||||||
|
stall_out <= '0';
|
||||||
|
if cr_read_in = '1' then
|
||||||
|
loop_0: for i in 0 to PIPELINE_DEPTH loop
|
||||||
|
if v(i).valid = '1' then
|
||||||
|
if r(i).bypass = '1' then
|
||||||
|
use_bypass <= '1';
|
||||||
|
else
|
||||||
|
stall_out <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- XXX assumes PIPELINE_DEPTH = 1
|
||||||
|
if busy_in = '0' then
|
||||||
|
v(1) := r(0);
|
||||||
|
v(0).valid := '0';
|
||||||
|
end if;
|
||||||
|
if deferred = '0' and issuing = '1' then
|
||||||
|
v(0).valid := cr_write_in;
|
||||||
|
v(0).bypass := bypassable;
|
||||||
|
end if;
|
||||||
|
if flush_in = '1' then
|
||||||
|
v(0).valid := '0';
|
||||||
|
v(1).valid := '0';
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- update registers
|
||||||
|
rin <= v;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
end;
|
@ -1,298 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.math_real.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
entity dmi_dtm is
|
|
||||||
generic(ABITS : INTEGER:=8;
|
|
||||||
DBITS : INTEGER:=64);
|
|
||||||
|
|
||||||
port(sys_clk : in std_ulogic;
|
|
||||||
sys_reset : in std_ulogic;
|
|
||||||
dmi_addr : out std_ulogic_vector(ABITS - 1 downto 0);
|
|
||||||
dmi_din : in std_ulogic_vector(DBITS - 1 downto 0);
|
|
||||||
dmi_dout : out std_ulogic_vector(DBITS - 1 downto 0);
|
|
||||||
dmi_req : out std_ulogic;
|
|
||||||
dmi_wr : out std_ulogic;
|
|
||||||
dmi_ack : in std_ulogic
|
|
||||||
-- dmi_err : in std_ulogic TODO: Add error response
|
|
||||||
);
|
|
||||||
end entity dmi_dtm;
|
|
||||||
|
|
||||||
architecture behaviour of dmi_dtm is
|
|
||||||
-- Signals coming out of the JTAGG block
|
|
||||||
signal jtag_reset_n : std_ulogic;
|
|
||||||
signal tdi : std_ulogic;
|
|
||||||
signal tdo : std_ulogic;
|
|
||||||
signal tck : std_ulogic;
|
|
||||||
signal jce1 : std_ulogic;
|
|
||||||
signal jshift : std_ulogic;
|
|
||||||
signal update : std_ulogic;
|
|
||||||
|
|
||||||
-- signals to match dmi_dtb_xilinx
|
|
||||||
signal jtag_reset : std_ulogic;
|
|
||||||
signal capture : std_ulogic;
|
|
||||||
signal jtag_clk : std_ulogic;
|
|
||||||
signal sel : std_ulogic;
|
|
||||||
signal shift : std_ulogic;
|
|
||||||
|
|
||||||
-- delays
|
|
||||||
signal jce1_d : std_ulogic;
|
|
||||||
constant TCK_DELAY : INTEGER := 8;
|
|
||||||
signal tck_d : std_ulogic_vector(TCK_DELAY+1 downto 1);
|
|
||||||
|
|
||||||
-- ** JTAG clock domain **
|
|
||||||
|
|
||||||
-- Shift register
|
|
||||||
signal shiftr : std_ulogic_vector(ABITS + DBITS + 1 downto 0);
|
|
||||||
|
|
||||||
-- Latched request
|
|
||||||
signal request : std_ulogic_vector(ABITS + DBITS + 1 downto 0);
|
|
||||||
|
|
||||||
-- A request is present
|
|
||||||
signal jtag_req : std_ulogic;
|
|
||||||
|
|
||||||
-- Synchronizer for jtag_rsp (sys clk -> jtag_clk)
|
|
||||||
signal dmi_ack_0 : std_ulogic;
|
|
||||||
signal dmi_ack_1 : std_ulogic;
|
|
||||||
|
|
||||||
-- ** sys clock domain **
|
|
||||||
|
|
||||||
-- Synchronizer for jtag_req (jtag clk -> sys clk)
|
|
||||||
signal jtag_req_0 : std_ulogic;
|
|
||||||
signal jtag_req_1 : std_ulogic;
|
|
||||||
|
|
||||||
-- ** combination signals
|
|
||||||
signal jtag_bsy : std_ulogic;
|
|
||||||
signal op_valid : std_ulogic;
|
|
||||||
signal rsp_op : std_ulogic_vector(1 downto 0);
|
|
||||||
|
|
||||||
-- ** Constants **
|
|
||||||
constant DMI_REQ_NOP : std_ulogic_vector(1 downto 0) := "00";
|
|
||||||
constant DMI_REQ_RD : std_ulogic_vector(1 downto 0) := "01";
|
|
||||||
constant DMI_REQ_WR : std_ulogic_vector(1 downto 0) := "10";
|
|
||||||
constant DMI_RSP_OK : std_ulogic_vector(1 downto 0) := "00";
|
|
||||||
constant DMI_RSP_BSY : std_ulogic_vector(1 downto 0) := "11";
|
|
||||||
|
|
||||||
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";
|
|
||||||
|
|
||||||
-- ECP5 JTAGG
|
|
||||||
component JTAGG is
|
|
||||||
generic (
|
|
||||||
ER1 : string := "ENABLED";
|
|
||||||
ER2 : string := "ENABLED"
|
|
||||||
);
|
|
||||||
port(
|
|
||||||
JTDO1 : in std_ulogic;
|
|
||||||
JTDO2 : in std_ulogic;
|
|
||||||
JTDI : out std_ulogic;
|
|
||||||
JTCK : out std_ulogic;
|
|
||||||
JRTI1 : out std_ulogic;
|
|
||||||
JRTI2 : out std_ulogic;
|
|
||||||
JSHIFT : out std_ulogic;
|
|
||||||
JUPDATE : out std_ulogic;
|
|
||||||
JRSTN : out std_ulogic;
|
|
||||||
JCE1 : out std_ulogic;
|
|
||||||
JCE2 : out std_ulogic
|
|
||||||
);
|
|
||||||
end component;
|
|
||||||
|
|
||||||
component LUT4 is
|
|
||||||
generic (
|
|
||||||
INIT : std_logic_vector
|
|
||||||
);
|
|
||||||
port(
|
|
||||||
A : in STD_ULOGIC;
|
|
||||||
B : in STD_ULOGIC;
|
|
||||||
C : in STD_ULOGIC;
|
|
||||||
D : in STD_ULOGIC;
|
|
||||||
Z : out STD_ULOGIC
|
|
||||||
);
|
|
||||||
end component;
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
jtag: JTAGG
|
|
||||||
generic map(
|
|
||||||
ER2 => "DISABLED"
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
JTDO1 => tdo,
|
|
||||||
JTDO2 => '0',
|
|
||||||
JTDI => tdi,
|
|
||||||
JTCK => tck,
|
|
||||||
JRTI1 => open,
|
|
||||||
JRTI2 => open,
|
|
||||||
JSHIFT => jshift,
|
|
||||||
JUPDATE => update,
|
|
||||||
JRSTN => jtag_reset_n,
|
|
||||||
JCE1 => jce1,
|
|
||||||
JCE2 => open
|
|
||||||
);
|
|
||||||
|
|
||||||
-- JRTI1 looks like it could be connected to SEL, but
|
|
||||||
-- in practise JRTI1 is only high briefly, not for the duration
|
|
||||||
-- of the transmission. possibly mw_debug could be modified.
|
|
||||||
-- The ecp5 is probably the only jtag device anyway.
|
|
||||||
sel <= '1';
|
|
||||||
|
|
||||||
-- TDI needs to align with TCK, we use LUT delays here.
|
|
||||||
-- From https://github.com/enjoy-digital/litex/pull/1087
|
|
||||||
tck_d(1) <= tck;
|
|
||||||
del: for i in 1 to TCK_DELAY generate
|
|
||||||
attribute keep : boolean;
|
|
||||||
attribute keep of l: label is true;
|
|
||||||
begin
|
|
||||||
l: LUT4
|
|
||||||
generic map(
|
|
||||||
INIT => b"0000_0000_0000_0010"
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
A => tck_d(i),
|
|
||||||
B => '0', C => '0', D => '0',
|
|
||||||
Z => tck_d(i+1)
|
|
||||||
);
|
|
||||||
end generate;
|
|
||||||
jtag_clk <= tck_d(TCK_DELAY+1);
|
|
||||||
|
|
||||||
-- capture signal
|
|
||||||
jce1_sync : process(jtag_clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(jtag_clk) then
|
|
||||||
jce1_d <= jce1;
|
|
||||||
capture <= jce1 and not jce1_d;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
-- latch the shift signal, otherwise
|
|
||||||
-- we miss the last shift in
|
|
||||||
-- (maybe because we are delaying tck?)
|
|
||||||
shift_sync : process(jtag_clk)
|
|
||||||
begin
|
|
||||||
if (sys_reset = '1') then
|
|
||||||
shift <= '0';
|
|
||||||
elsif rising_edge(jtag_clk) then
|
|
||||||
shift <= jshift;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
jtag_reset <= not jtag_reset_n;
|
|
||||||
|
|
||||||
-- dmi_req synchronization
|
|
||||||
dmi_req_sync : process(sys_clk)
|
|
||||||
begin
|
|
||||||
-- sys_reset is synchronous
|
|
||||||
if rising_edge(sys_clk) then
|
|
||||||
if (sys_reset = '1') then
|
|
||||||
jtag_req_0 <= '0';
|
|
||||||
jtag_req_1 <= '0';
|
|
||||||
else
|
|
||||||
jtag_req_0 <= jtag_req;
|
|
||||||
jtag_req_1 <= jtag_req_0;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
dmi_req <= jtag_req_1;
|
|
||||||
|
|
||||||
-- dmi_ack synchronization
|
|
||||||
dmi_ack_sync: process(jtag_clk, jtag_reset)
|
|
||||||
begin
|
|
||||||
-- jtag_reset is async (see comments)
|
|
||||||
if jtag_reset = '1' then
|
|
||||||
dmi_ack_0 <= '0';
|
|
||||||
dmi_ack_1 <= '0';
|
|
||||||
elsif rising_edge(jtag_clk) then
|
|
||||||
dmi_ack_0 <= dmi_ack;
|
|
||||||
dmi_ack_1 <= dmi_ack_0;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
-- jtag_bsy indicates whether we can start a new request, we can when
|
|
||||||
-- we aren't already processing one (jtag_req) and the synchronized ack
|
|
||||||
-- of the previous one is 0.
|
|
||||||
--
|
|
||||||
jtag_bsy <= jtag_req or dmi_ack_1;
|
|
||||||
|
|
||||||
-- decode request type in shift register
|
|
||||||
with shiftr(1 downto 0) select op_valid <=
|
|
||||||
'1' when DMI_REQ_RD,
|
|
||||||
'1' when DMI_REQ_WR,
|
|
||||||
'0' when others;
|
|
||||||
|
|
||||||
-- encode response op
|
|
||||||
rsp_op <= DMI_RSP_BSY when jtag_bsy = '1' else DMI_RSP_OK;
|
|
||||||
|
|
||||||
-- Some DMI out signals are directly driven from the request register
|
|
||||||
dmi_addr <= request(ABITS + DBITS + 1 downto DBITS + 2);
|
|
||||||
dmi_dout <= request(DBITS + 1 downto 2);
|
|
||||||
dmi_wr <= '1' when request(1 downto 0) = DMI_REQ_WR else '0';
|
|
||||||
|
|
||||||
-- TDO is wired to shift register bit 0
|
|
||||||
tdo <= shiftr(0);
|
|
||||||
|
|
||||||
-- Main state machine. Handles shift registers, request latch and
|
|
||||||
-- jtag_req latch. Could be split into 3 processes but it's probably
|
|
||||||
-- not worthwhile.
|
|
||||||
--
|
|
||||||
shifter: process(jtag_clk, jtag_reset, sys_reset)
|
|
||||||
begin
|
|
||||||
if jtag_reset = '1' or sys_reset = '1' then
|
|
||||||
shiftr <= (others => '0');
|
|
||||||
jtag_req <= '0';
|
|
||||||
request <= (others => '0');
|
|
||||||
elsif rising_edge(jtag_clk) then
|
|
||||||
|
|
||||||
-- Handle jtag "commands" when sel is 1
|
|
||||||
if sel = '1' then
|
|
||||||
-- Shift state, rotate the register
|
|
||||||
if shift = '1' then
|
|
||||||
shiftr <= tdi & shiftr(ABITS + DBITS + 1 downto 1);
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Update state (trigger)
|
|
||||||
--
|
|
||||||
-- Latch the request if we aren't already processing one and
|
|
||||||
-- it has a valid command opcode.
|
|
||||||
--
|
|
||||||
if update = '1' and op_valid = '1' then
|
|
||||||
if jtag_bsy = '0' then
|
|
||||||
request <= shiftr;
|
|
||||||
jtag_req <= '1';
|
|
||||||
end if;
|
|
||||||
-- Set the shift register "op" to "busy". This will prevent
|
|
||||||
-- us from re-starting the command on the next update if
|
|
||||||
-- the command completes before that.
|
|
||||||
shiftr(1 downto 0) <= DMI_RSP_BSY;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Request completion.
|
|
||||||
--
|
|
||||||
-- Capture the response data for reads and clear request flag.
|
|
||||||
--
|
|
||||||
-- Note: We clear req (and thus dmi_req) here which relies on tck
|
|
||||||
-- ticking and sel set. This means we are stuck with dmi_req up if
|
|
||||||
-- the jtag interface stops. Slaves must be resilient to this.
|
|
||||||
--
|
|
||||||
if jtag_req = '1' and dmi_ack_1 = '1' then
|
|
||||||
jtag_req <= '0';
|
|
||||||
if request(1 downto 0) = DMI_REQ_RD then
|
|
||||||
request(DBITS + 1 downto 2) <= dmi_din;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
-- Capture state, grab latch content with updated status
|
|
||||||
if capture = '1' then
|
|
||||||
shiftr <= request(ABITS + DBITS + 1 downto 2) & rsp_op;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
end architecture behaviour;
|
|
||||||
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
@ -1,30 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.glibc_random.all;
|
|
||||||
|
|
||||||
entity random is
|
|
||||||
port (
|
|
||||||
clk : in std_ulogic;
|
|
||||||
data : out std_ulogic_vector(63 downto 0);
|
|
||||||
raw : out std_ulogic_vector(63 downto 0);
|
|
||||||
err : out std_ulogic
|
|
||||||
);
|
|
||||||
end entity random;
|
|
||||||
|
|
||||||
architecture behaviour of random is
|
|
||||||
begin
|
|
||||||
err <= '0';
|
|
||||||
|
|
||||||
process(clk)
|
|
||||||
variable rand : std_ulogic_vector(63 downto 0);
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
rand := pseudorand(64);
|
|
||||||
data <= rand;
|
|
||||||
raw <= rand;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
end behaviour;
|
|
@ -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;
|
@ -1,512 +0,0 @@
|
|||||||
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 := 16384;
|
|
||||||
RAM_INIT_FILE : string := "firmware.hex";
|
|
||||||
RESET_LOW : boolean := true;
|
|
||||||
CLK_INPUT : positive := 100000000;
|
|
||||||
CLK_FREQUENCY : positive := 100000000;
|
|
||||||
HAS_FPU : boolean := true;
|
|
||||||
HAS_BTC : boolean := false;
|
|
||||||
USE_LITEDRAM : boolean := true;
|
|
||||||
NO_BRAM : boolean := true;
|
|
||||||
SCLK_STARTUPE2 : boolean := false;
|
|
||||||
SPI_FLASH_OFFSET : integer := 4194304;
|
|
||||||
SPI_FLASH_DEF_CKDV : natural := 1;
|
|
||||||
SPI_FLASH_DEF_QUAD : boolean := true;
|
|
||||||
LOG_LENGTH : natural := 0;
|
|
||||||
UART_IS_16550 : boolean := true;
|
|
||||||
HAS_UART1 : boolean := false;
|
|
||||||
USE_LITESDCARD : boolean := true;
|
|
||||||
ICACHE_NUM_LINES : natural := 64;
|
|
||||||
NGPIO : natural := 0
|
|
||||||
);
|
|
||||||
port(
|
|
||||||
ext_clk : in std_ulogic;
|
|
||||||
ext_rst_n : in std_ulogic;
|
|
||||||
|
|
||||||
-- UART0 signals:
|
|
||||||
pin_gpio_0 : out std_ulogic;
|
|
||||||
pin_gpio_1 : in std_ulogic;
|
|
||||||
|
|
||||||
-- LEDs
|
|
||||||
led0_b : out std_ulogic;
|
|
||||||
led0_g : out std_ulogic;
|
|
||||||
led0_r : out std_ulogic;
|
|
||||||
|
|
||||||
-- SPI
|
|
||||||
spi_flash_cs_n : out std_ulogic;
|
|
||||||
spi_flash_mosi : inout std_ulogic;
|
|
||||||
spi_flash_miso : inout std_ulogic;
|
|
||||||
spi_flash_wp_n : inout std_ulogic;
|
|
||||||
spi_flash_hold_n : inout std_ulogic;
|
|
||||||
|
|
||||||
-- SD card wires
|
|
||||||
sdcard_data : inout std_ulogic_vector(3 downto 0);
|
|
||||||
sdcard_cmd : inout std_ulogic;
|
|
||||||
sdcard_clk : out std_ulogic;
|
|
||||||
sdcard_cd : in std_ulogic;
|
|
||||||
|
|
||||||
-- DRAM wires
|
|
||||||
ddram_a : out std_ulogic_vector(13 downto 0);
|
|
||||||
ddram_ba : out std_ulogic_vector(2 downto 0);
|
|
||||||
ddram_ras_n : out std_ulogic;
|
|
||||||
ddram_cas_n : out std_ulogic;
|
|
||||||
ddram_we_n : out std_ulogic;
|
|
||||||
ddram_cs_n : out std_ulogic;
|
|
||||||
ddram_dm : out std_ulogic_vector(1 downto 0);
|
|
||||||
ddram_dq : inout std_ulogic_vector(15 downto 0);
|
|
||||||
ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
|
|
||||||
ddram_clk_p : out std_ulogic_vector(0 downto 0);
|
|
||||||
-- only the positive differential pin is instantiated
|
|
||||||
--ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
|
|
||||||
--ddram_clk_n : out std_ulogic_vector(0 downto 0);
|
|
||||||
ddram_cke : out std_ulogic;
|
|
||||||
ddram_odt : out std_ulogic;
|
|
||||||
ddram_reset_n : out std_ulogic;
|
|
||||||
|
|
||||||
ddram_gnd : out std_ulogic_vector(1 downto 0);
|
|
||||||
ddram_vccio : out std_ulogic_vector(5 downto 0)
|
|
||||||
);
|
|
||||||
end entity toplevel;
|
|
||||||
|
|
||||||
architecture behaviour of toplevel is
|
|
||||||
|
|
||||||
-- Reset signals:
|
|
||||||
signal soc_rst : std_ulogic;
|
|
||||||
signal pll_rst : std_ulogic;
|
|
||||||
|
|
||||||
-- Internal clock signals:
|
|
||||||
signal system_clk : std_ulogic;
|
|
||||||
signal system_clk_locked : std_ulogic;
|
|
||||||
|
|
||||||
-- External IOs from the SoC
|
|
||||||
signal wb_ext_io_in : wb_io_master_out;
|
|
||||||
signal wb_ext_io_out : wb_io_slave_out;
|
|
||||||
signal wb_ext_is_dram_csr : std_ulogic;
|
|
||||||
signal wb_ext_is_dram_init : std_ulogic;
|
|
||||||
signal wb_ext_is_sdcard : std_ulogic;
|
|
||||||
|
|
||||||
-- DRAM main data wishbone connection
|
|
||||||
signal wb_dram_in : wishbone_master_out;
|
|
||||||
signal wb_dram_out : wishbone_slave_out;
|
|
||||||
|
|
||||||
-- DRAM control wishbone connection
|
|
||||||
signal wb_dram_ctrl_out : wb_io_slave_out := wb_io_slave_out_init;
|
|
||||||
|
|
||||||
-- LiteSDCard connection
|
|
||||||
signal ext_irq_sdcard : std_ulogic := '0';
|
|
||||||
signal wb_sdcard_out : wb_io_slave_out := wb_io_slave_out_init;
|
|
||||||
signal wb_sddma_out : wb_io_master_out := wb_io_master_out_init;
|
|
||||||
signal wb_sddma_in : wb_io_slave_out;
|
|
||||||
signal wb_sddma_nr : wb_io_master_out;
|
|
||||||
signal wb_sddma_ir : wb_io_slave_out;
|
|
||||||
-- for conversion from non-pipelined wishbone to pipelined
|
|
||||||
signal wb_sddma_stb_sent : std_ulogic;
|
|
||||||
|
|
||||||
-- Control/status
|
|
||||||
signal core_alt_reset : std_ulogic;
|
|
||||||
|
|
||||||
-- Status LED
|
|
||||||
signal led0_b_pwm : std_ulogic;
|
|
||||||
signal led0_r_pwm : std_ulogic;
|
|
||||||
signal led0_g_pwm : std_ulogic;
|
|
||||||
|
|
||||||
-- Dumb PWM for the LEDs, those RGB LEDs are too bright otherwise
|
|
||||||
signal pwm_counter : std_ulogic_vector(8 downto 0);
|
|
||||||
|
|
||||||
-- SPI flash
|
|
||||||
signal spi_sck : std_ulogic;
|
|
||||||
signal spi_cs_n : std_ulogic;
|
|
||||||
signal spi_sdat_o : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_i : std_ulogic_vector(3 downto 0);
|
|
||||||
|
|
||||||
-- GPIO
|
|
||||||
signal gpio_in : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
signal gpio_out : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
signal gpio_dir : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
|
|
||||||
-- Fixup various memory sizes based on generics
|
|
||||||
function get_bram_size return natural is
|
|
||||||
begin
|
|
||||||
if USE_LITEDRAM and NO_BRAM then
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return MEMORY_SIZE;
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
function get_payload_size return natural is
|
|
||||||
begin
|
|
||||||
if USE_LITEDRAM and NO_BRAM then
|
|
||||||
return MEMORY_SIZE;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
constant BRAM_SIZE : natural := get_bram_size;
|
|
||||||
constant PAYLOAD_SIZE : natural := get_payload_size;
|
|
||||||
|
|
||||||
COMPONENT USRMCLK
|
|
||||||
PORT(
|
|
||||||
USRMCLKI : IN STD_ULOGIC;
|
|
||||||
USRMCLKTS : IN STD_ULOGIC
|
|
||||||
);
|
|
||||||
END COMPONENT;
|
|
||||||
attribute syn_noprune: boolean ;
|
|
||||||
attribute syn_noprune of USRMCLK: component is true;
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Main SoC
|
|
||||||
soc0: entity work.soc
|
|
||||||
generic map(
|
|
||||||
MEMORY_SIZE => BRAM_SIZE,
|
|
||||||
RAM_INIT_FILE => RAM_INIT_FILE,
|
|
||||||
SIM => false,
|
|
||||||
CLK_FREQ => CLK_FREQUENCY,
|
|
||||||
HAS_FPU => HAS_FPU,
|
|
||||||
HAS_BTC => HAS_BTC,
|
|
||||||
HAS_DRAM => USE_LITEDRAM,
|
|
||||||
DRAM_SIZE => 256 * 1024 * 1024,
|
|
||||||
DRAM_INIT_SIZE => PAYLOAD_SIZE,
|
|
||||||
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_SD_CARD => USE_LITESDCARD,
|
|
||||||
ICACHE_NUM_LINES => ICACHE_NUM_LINES,
|
|
||||||
HAS_SHORT_MULT => true,
|
|
||||||
NGPIO => NGPIO
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
-- System signals
|
|
||||||
system_clk => system_clk,
|
|
||||||
rst => soc_rst,
|
|
||||||
|
|
||||||
-- UART signals
|
|
||||||
uart0_txd => pin_gpio_0,
|
|
||||||
uart0_rxd => pin_gpio_1,
|
|
||||||
|
|
||||||
-- UART1 signals
|
|
||||||
--uart1_txd => uart_pmod_tx,
|
|
||||||
--uart1_rxd => uart_pmod_rx,
|
|
||||||
|
|
||||||
-- SPI signals
|
|
||||||
spi_flash_sck => spi_sck,
|
|
||||||
spi_flash_cs_n => spi_cs_n,
|
|
||||||
spi_flash_sdat_o => spi_sdat_o,
|
|
||||||
spi_flash_sdat_oe => spi_sdat_oe,
|
|
||||||
spi_flash_sdat_i => spi_sdat_i,
|
|
||||||
|
|
||||||
-- GPIO signals
|
|
||||||
gpio_in => gpio_in,
|
|
||||||
gpio_out => gpio_out,
|
|
||||||
gpio_dir => gpio_dir,
|
|
||||||
|
|
||||||
-- External interrupts
|
|
||||||
ext_irq_sdcard => ext_irq_sdcard,
|
|
||||||
|
|
||||||
-- DRAM wishbone
|
|
||||||
wb_dram_in => wb_dram_in,
|
|
||||||
wb_dram_out => wb_dram_out,
|
|
||||||
|
|
||||||
-- IO wishbone
|
|
||||||
wb_ext_io_in => wb_ext_io_in,
|
|
||||||
wb_ext_io_out => wb_ext_io_out,
|
|
||||||
wb_ext_is_dram_csr => wb_ext_is_dram_csr,
|
|
||||||
wb_ext_is_dram_init => wb_ext_is_dram_init,
|
|
||||||
wb_ext_is_sdcard => wb_ext_is_sdcard,
|
|
||||||
|
|
||||||
-- DMA wishbone
|
|
||||||
wishbone_dma_in => wb_sddma_in,
|
|
||||||
wishbone_dma_out => wb_sddma_out,
|
|
||||||
|
|
||||||
alt_reset => core_alt_reset
|
|
||||||
);
|
|
||||||
|
|
||||||
-- SPI Flash
|
|
||||||
--
|
|
||||||
spi_flash_cs_n <= spi_cs_n;
|
|
||||||
spi_flash_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
|
|
||||||
spi_flash_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
|
|
||||||
spi_flash_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
|
|
||||||
spi_flash_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else 'Z';
|
|
||||||
spi_sdat_i(0) <= spi_flash_mosi;
|
|
||||||
spi_sdat_i(1) <= spi_flash_miso;
|
|
||||||
spi_sdat_i(2) <= spi_flash_wp_n;
|
|
||||||
spi_sdat_i(3) <= spi_flash_hold_n;
|
|
||||||
|
|
||||||
uclk: USRMCLK port map (
|
|
||||||
USRMCLKI => spi_sck,
|
|
||||||
USRMCLKTS => '0'
|
|
||||||
);
|
|
||||||
|
|
||||||
nodram: if not USE_LITEDRAM generate
|
|
||||||
signal ddram_clk_dummy : std_ulogic;
|
|
||||||
begin
|
|
||||||
reset_controller: entity work.soc_reset
|
|
||||||
generic map(
|
|
||||||
RESET_LOW => RESET_LOW
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_clk => system_clk,
|
|
||||||
pll_locked_in => system_clk_locked,
|
|
||||||
ext_rst_in => ext_rst_n,
|
|
||||||
pll_rst_out => pll_rst,
|
|
||||||
rst_out => soc_rst
|
|
||||||
);
|
|
||||||
|
|
||||||
clkgen: entity work.clock_generator
|
|
||||||
generic map(
|
|
||||||
CLK_INPUT_HZ => CLK_INPUT,
|
|
||||||
CLK_OUTPUT_HZ => CLK_FREQUENCY
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_rst_in => pll_rst,
|
|
||||||
pll_clk_out => system_clk,
|
|
||||||
pll_locked_out => system_clk_locked
|
|
||||||
);
|
|
||||||
|
|
||||||
led0_b_pwm <= '1';
|
|
||||||
led0_r_pwm <= '1';
|
|
||||||
led0_g_pwm <= '0';
|
|
||||||
core_alt_reset <= '0';
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
has_dram: if USE_LITEDRAM generate
|
|
||||||
signal dram_init_done : std_ulogic;
|
|
||||||
signal dram_init_error : std_ulogic;
|
|
||||||
signal dram_sys_rst : std_ulogic;
|
|
||||||
signal rst_gen_rst : std_ulogic;
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Eventually dig out the frequency from
|
|
||||||
-- litesdram generate.py sys_clk_freq
|
|
||||||
-- but for now, assert it's 48Mhz for orangecrab
|
|
||||||
assert CLK_FREQUENCY = 48000000;
|
|
||||||
|
|
||||||
reset_controller: entity work.soc_reset
|
|
||||||
generic map(
|
|
||||||
RESET_LOW => RESET_LOW,
|
|
||||||
PLL_RESET_BITS => 18,
|
|
||||||
SOC_RESET_BITS => 1
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_clk => system_clk,
|
|
||||||
pll_locked_in => system_clk_locked,
|
|
||||||
ext_rst_in => ext_rst_n,
|
|
||||||
pll_rst_out => pll_rst,
|
|
||||||
rst_out => rst_gen_rst
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Generate SoC reset
|
|
||||||
soc_rst_gen: process(system_clk)
|
|
||||||
begin
|
|
||||||
if ext_rst_n = '0' then
|
|
||||||
soc_rst <= '1';
|
|
||||||
elsif rising_edge(system_clk) then
|
|
||||||
soc_rst <= dram_sys_rst or not system_clk_locked;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
dram: entity work.litedram_wrapper
|
|
||||||
generic map(
|
|
||||||
DRAM_ABITS => 24,
|
|
||||||
DRAM_ALINES => 14,
|
|
||||||
DRAM_DLINES => 16,
|
|
||||||
DRAM_CKLINES => 1,
|
|
||||||
DRAM_PORT_WIDTH => 128,
|
|
||||||
NUM_LINES => 8, -- reduce from default of 64 to make smaller/timing
|
|
||||||
PAYLOAD_FILE => RAM_INIT_FILE,
|
|
||||||
PAYLOAD_SIZE => PAYLOAD_SIZE
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
clk_in => ext_clk,
|
|
||||||
rst => pll_rst,
|
|
||||||
system_clk => system_clk,
|
|
||||||
system_reset => dram_sys_rst,
|
|
||||||
core_alt_reset => core_alt_reset,
|
|
||||||
pll_locked => system_clk_locked,
|
|
||||||
|
|
||||||
wb_in => wb_dram_in,
|
|
||||||
wb_out => wb_dram_out,
|
|
||||||
wb_ctrl_in => wb_ext_io_in,
|
|
||||||
wb_ctrl_out => wb_dram_ctrl_out,
|
|
||||||
wb_ctrl_is_csr => wb_ext_is_dram_csr,
|
|
||||||
wb_ctrl_is_init => wb_ext_is_dram_init,
|
|
||||||
|
|
||||||
init_done => dram_init_done,
|
|
||||||
init_error => dram_init_error,
|
|
||||||
|
|
||||||
ddram_a => ddram_a,
|
|
||||||
ddram_ba => ddram_ba,
|
|
||||||
ddram_ras_n => ddram_ras_n,
|
|
||||||
ddram_cas_n => ddram_cas_n,
|
|
||||||
ddram_we_n => ddram_we_n,
|
|
||||||
ddram_cs_n => ddram_cs_n,
|
|
||||||
ddram_dm => ddram_dm,
|
|
||||||
ddram_dq => ddram_dq,
|
|
||||||
ddram_dqs_p => ddram_dqs_p,
|
|
||||||
ddram_clk_p => ddram_clk_p,
|
|
||||||
-- only the positive differential pin is instantiated
|
|
||||||
--ddram_dqs_n => ddram_dqs_n,
|
|
||||||
--ddram_clk_n => ddram_clk_n,
|
|
||||||
ddram_cke => ddram_cke,
|
|
||||||
ddram_odt => ddram_odt,
|
|
||||||
|
|
||||||
ddram_reset_n => ddram_reset_n
|
|
||||||
);
|
|
||||||
|
|
||||||
ddram_gnd <= "00";
|
|
||||||
-- for power consumption.
|
|
||||||
-- https://github.com/orangecrab-fpga/orangecrab-hardware/issues/19#issuecomment-683479378
|
|
||||||
ddram_vccio <= "111111";
|
|
||||||
|
|
||||||
led0_b_pwm <= not dram_init_done;
|
|
||||||
led0_r_pwm <= dram_init_error;
|
|
||||||
led0_g_pwm <= dram_init_done and not dram_init_error;
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
|
|
||||||
-- SD card pmod
|
|
||||||
has_sdcard : if USE_LITESDCARD generate
|
|
||||||
component litesdcard_core port (
|
|
||||||
clk : in std_ulogic;
|
|
||||||
rst : in std_ulogic;
|
|
||||||
-- wishbone for accessing control registers
|
|
||||||
wb_ctrl_adr : in std_ulogic_vector(29 downto 0);
|
|
||||||
wb_ctrl_dat_w : in std_ulogic_vector(31 downto 0);
|
|
||||||
wb_ctrl_dat_r : out std_ulogic_vector(31 downto 0);
|
|
||||||
wb_ctrl_sel : in std_ulogic_vector(3 downto 0);
|
|
||||||
wb_ctrl_cyc : in std_ulogic;
|
|
||||||
wb_ctrl_stb : in std_ulogic;
|
|
||||||
wb_ctrl_ack : out std_ulogic;
|
|
||||||
wb_ctrl_we : in std_ulogic;
|
|
||||||
wb_ctrl_cti : in std_ulogic_vector(2 downto 0);
|
|
||||||
wb_ctrl_bte : in std_ulogic_vector(1 downto 0);
|
|
||||||
wb_ctrl_err : out std_ulogic;
|
|
||||||
-- wishbone for SD card core to use for DMA
|
|
||||||
wb_dma_adr : out std_ulogic_vector(29 downto 0);
|
|
||||||
wb_dma_dat_w : out std_ulogic_vector(31 downto 0);
|
|
||||||
wb_dma_dat_r : in std_ulogic_vector(31 downto 0);
|
|
||||||
wb_dma_sel : out std_ulogic_vector(3 downto 0);
|
|
||||||
wb_dma_cyc : out std_ulogic;
|
|
||||||
wb_dma_stb : out std_ulogic;
|
|
||||||
wb_dma_ack : in std_ulogic;
|
|
||||||
wb_dma_we : out std_ulogic;
|
|
||||||
wb_dma_cti : out std_ulogic_vector(2 downto 0);
|
|
||||||
wb_dma_bte : out std_ulogic_vector(1 downto 0);
|
|
||||||
wb_dma_err : in std_ulogic;
|
|
||||||
-- connections to SD card
|
|
||||||
sdcard_data : inout std_ulogic_vector(3 downto 0);
|
|
||||||
sdcard_cmd : inout std_ulogic;
|
|
||||||
sdcard_clk : out std_ulogic;
|
|
||||||
sdcard_cd : in std_ulogic;
|
|
||||||
irq : out std_ulogic
|
|
||||||
);
|
|
||||||
end component;
|
|
||||||
|
|
||||||
signal wb_sdcard_cyc : std_ulogic;
|
|
||||||
signal wb_sdcard_adr : std_ulogic_vector(29 downto 0);
|
|
||||||
|
|
||||||
begin
|
|
||||||
litesdcard : litesdcard_core
|
|
||||||
port map (
|
|
||||||
clk => system_clk,
|
|
||||||
rst => soc_rst,
|
|
||||||
wb_ctrl_adr => wb_sdcard_adr,
|
|
||||||
wb_ctrl_dat_w => wb_ext_io_in.dat,
|
|
||||||
wb_ctrl_dat_r => wb_sdcard_out.dat,
|
|
||||||
wb_ctrl_sel => wb_ext_io_in.sel,
|
|
||||||
wb_ctrl_cyc => wb_sdcard_cyc,
|
|
||||||
wb_ctrl_stb => wb_ext_io_in.stb,
|
|
||||||
wb_ctrl_ack => wb_sdcard_out.ack,
|
|
||||||
wb_ctrl_we => wb_ext_io_in.we,
|
|
||||||
wb_ctrl_cti => "000",
|
|
||||||
wb_ctrl_bte => "00",
|
|
||||||
wb_ctrl_err => open,
|
|
||||||
wb_dma_adr => wb_sddma_nr.adr,
|
|
||||||
wb_dma_dat_w => wb_sddma_nr.dat,
|
|
||||||
wb_dma_dat_r => wb_sddma_ir.dat,
|
|
||||||
wb_dma_sel => wb_sddma_nr.sel,
|
|
||||||
wb_dma_cyc => wb_sddma_nr.cyc,
|
|
||||||
wb_dma_stb => wb_sddma_nr.stb,
|
|
||||||
wb_dma_ack => wb_sddma_ir.ack,
|
|
||||||
wb_dma_we => wb_sddma_nr.we,
|
|
||||||
wb_dma_cti => open,
|
|
||||||
wb_dma_bte => open,
|
|
||||||
wb_dma_err => '0',
|
|
||||||
sdcard_data => sdcard_data,
|
|
||||||
sdcard_cmd => sdcard_cmd,
|
|
||||||
sdcard_clk => sdcard_clk,
|
|
||||||
sdcard_cd => sdcard_cd,
|
|
||||||
irq => ext_irq_sdcard
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Gate cyc with chip select from SoC
|
|
||||||
wb_sdcard_cyc <= wb_ext_io_in.cyc and wb_ext_is_sdcard;
|
|
||||||
|
|
||||||
wb_sdcard_adr <= x"0000" & wb_ext_io_in.adr(13 downto 0);
|
|
||||||
|
|
||||||
wb_sdcard_out.stall <= not wb_sdcard_out.ack;
|
|
||||||
|
|
||||||
-- Convert non-pipelined DMA wishbone to pipelined by suppressing
|
|
||||||
-- non-acknowledged strobes
|
|
||||||
process(system_clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(system_clk) then
|
|
||||||
wb_sddma_out <= wb_sddma_nr;
|
|
||||||
if wb_sddma_stb_sent = '1' or
|
|
||||||
(wb_sddma_out.stb = '1' and wb_sddma_in.stall = '0') then
|
|
||||||
wb_sddma_out.stb <= '0';
|
|
||||||
end if;
|
|
||||||
if wb_sddma_nr.cyc = '0' or wb_sddma_ir.ack = '1' then
|
|
||||||
wb_sddma_stb_sent <= '0';
|
|
||||||
elsif wb_sddma_in.stall = '0' then
|
|
||||||
wb_sddma_stb_sent <= wb_sddma_nr.stb;
|
|
||||||
end if;
|
|
||||||
wb_sddma_ir <= wb_sddma_in;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
-- Mux WB response on the IO bus
|
|
||||||
wb_ext_io_out <= wb_sdcard_out when wb_ext_is_sdcard = '1' else
|
|
||||||
wb_dram_ctrl_out;
|
|
||||||
|
|
||||||
leds_pwm : process(system_clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(system_clk) then
|
|
||||||
pwm_counter <= std_ulogic_vector(signed(pwm_counter) + 1);
|
|
||||||
if pwm_counter(8 downto 4) = "00000" then
|
|
||||||
led0_b <= led0_b_pwm;
|
|
||||||
led0_r <= led0_r_pwm;
|
|
||||||
led0_g <= led0_g_pwm;
|
|
||||||
else
|
|
||||||
led0_b <= '0';
|
|
||||||
led0_r <= '0';
|
|
||||||
led0_g <= '0';
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end architecture behaviour;
|
|
@ -1,587 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library unisim;
|
|
||||||
use unisim.vcomponents.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
entity toplevel is
|
|
||||||
generic (
|
|
||||||
MEMORY_SIZE : integer := 16384;
|
|
||||||
RAM_INIT_FILE : string := "firmware.hex";
|
|
||||||
RESET_LOW : boolean := true;
|
|
||||||
CLK_FREQUENCY : positive := 100000000;
|
|
||||||
HAS_FPU : boolean := true;
|
|
||||||
HAS_BTC : boolean := true;
|
|
||||||
HAS_SHORT_MULT : boolean := false;
|
|
||||||
USE_LITEDRAM : boolean := false;
|
|
||||||
NO_BRAM : boolean := false;
|
|
||||||
DISABLE_FLATTEN_CORE : boolean := false;
|
|
||||||
SPI_FLASH_OFFSET : integer := 4194304;
|
|
||||||
SPI_FLASH_DEF_CKDV : natural := 1;
|
|
||||||
SPI_FLASH_DEF_QUAD : boolean := true;
|
|
||||||
LOG_LENGTH : natural := 512;
|
|
||||||
USE_LITEETH : boolean := false;
|
|
||||||
UART_IS_16550 : boolean := true;
|
|
||||||
HAS_UART1 : boolean := false;
|
|
||||||
USE_LITESDCARD : boolean := false;
|
|
||||||
HAS_GPIO : boolean := false;
|
|
||||||
NGPIO : natural := 32
|
|
||||||
);
|
|
||||||
port(
|
|
||||||
ext_clk : in std_ulogic;
|
|
||||||
ext_rst_n : in std_ulogic;
|
|
||||||
|
|
||||||
-- UART0 signals:
|
|
||||||
uart_main_tx : out std_ulogic;
|
|
||||||
uart_main_rx : in std_ulogic;
|
|
||||||
|
|
||||||
-- LEDs
|
|
||||||
led0_n : out std_ulogic;
|
|
||||||
led1_n : out std_ulogic;
|
|
||||||
|
|
||||||
-- SPI
|
|
||||||
spi_flash_cs_n : out std_ulogic;
|
|
||||||
spi_flash_mosi : inout std_ulogic;
|
|
||||||
spi_flash_miso : inout std_ulogic;
|
|
||||||
spi_flash_wp_n : inout std_ulogic;
|
|
||||||
spi_flash_hold_n : inout std_ulogic;
|
|
||||||
|
|
||||||
-- Ethernet
|
|
||||||
eth_clocks_tx : in std_ulogic;
|
|
||||||
eth_clocks_gtx : out std_ulogic;
|
|
||||||
eth_clocks_rx : in std_ulogic;
|
|
||||||
eth_rst_n : out std_ulogic;
|
|
||||||
eth_mdio : inout std_ulogic;
|
|
||||||
eth_mdc : out std_ulogic;
|
|
||||||
eth_rx_dv : in std_ulogic;
|
|
||||||
eth_rx_er : in std_ulogic;
|
|
||||||
eth_rx_data : in std_ulogic_vector(7 downto 0);
|
|
||||||
eth_tx_en : out std_ulogic;
|
|
||||||
eth_tx_er : out std_ulogic;
|
|
||||||
eth_tx_data : out std_ulogic_vector(7 downto 0);
|
|
||||||
eth_col : in std_ulogic;
|
|
||||||
eth_crs : in std_ulogic;
|
|
||||||
|
|
||||||
-- SD card
|
|
||||||
sdcard_data : inout std_ulogic_vector(3 downto 0);
|
|
||||||
sdcard_cmd : inout std_ulogic;
|
|
||||||
sdcard_clk : out std_ulogic;
|
|
||||||
sdcard_cd : in std_ulogic;
|
|
||||||
|
|
||||||
-- DRAM wires
|
|
||||||
ddram_a : out std_ulogic_vector(13 downto 0);
|
|
||||||
ddram_ba : out std_ulogic_vector(2 downto 0);
|
|
||||||
ddram_ras_n : out std_ulogic;
|
|
||||||
ddram_cas_n : out std_ulogic;
|
|
||||||
ddram_we_n : out std_ulogic;
|
|
||||||
ddram_dm : out std_ulogic_vector(1 downto 0);
|
|
||||||
ddram_dq : inout std_ulogic_vector(15 downto 0);
|
|
||||||
ddram_dqs_p : inout std_ulogic_vector(1 downto 0);
|
|
||||||
ddram_dqs_n : inout std_ulogic_vector(1 downto 0);
|
|
||||||
ddram_clk_p : out std_ulogic;
|
|
||||||
ddram_clk_n : out std_ulogic;
|
|
||||||
ddram_cke : out std_ulogic;
|
|
||||||
ddram_odt : out std_ulogic;
|
|
||||||
ddram_reset_n : out std_ulogic
|
|
||||||
);
|
|
||||||
end entity toplevel;
|
|
||||||
|
|
||||||
architecture behaviour of toplevel is
|
|
||||||
|
|
||||||
-- Reset signals:
|
|
||||||
signal soc_rst : std_ulogic;
|
|
||||||
signal pll_rst : std_ulogic;
|
|
||||||
|
|
||||||
-- Internal clock signals:
|
|
||||||
signal system_clk : std_ulogic;
|
|
||||||
signal system_clk_locked : std_ulogic;
|
|
||||||
|
|
||||||
-- External IOs from the SoC
|
|
||||||
signal wb_ext_io_in : wb_io_master_out;
|
|
||||||
signal wb_ext_io_out : wb_io_slave_out;
|
|
||||||
signal wb_ext_is_dram_csr : std_ulogic;
|
|
||||||
signal wb_ext_is_dram_init : std_ulogic;
|
|
||||||
signal wb_ext_is_eth : std_ulogic;
|
|
||||||
signal wb_ext_is_sdcard : std_ulogic;
|
|
||||||
|
|
||||||
-- DRAM main data wishbone connection
|
|
||||||
signal wb_dram_in : wishbone_master_out;
|
|
||||||
signal wb_dram_out : wishbone_slave_out;
|
|
||||||
|
|
||||||
-- DRAM control wishbone connection
|
|
||||||
signal wb_dram_ctrl_out : wb_io_slave_out := wb_io_slave_out_init;
|
|
||||||
|
|
||||||
-- LiteEth connection
|
|
||||||
signal ext_irq_eth : std_ulogic;
|
|
||||||
signal wb_eth_out : wb_io_slave_out := wb_io_slave_out_init;
|
|
||||||
|
|
||||||
-- LiteSDCard connection
|
|
||||||
signal ext_irq_sdcard : std_ulogic := '0';
|
|
||||||
signal wb_sdcard_out : wb_io_slave_out := wb_io_slave_out_init;
|
|
||||||
signal wb_sddma_out : wb_io_master_out := wb_io_master_out_init;
|
|
||||||
signal wb_sddma_in : wb_io_slave_out;
|
|
||||||
signal wb_sddma_nr : wb_io_master_out;
|
|
||||||
signal wb_sddma_ir : wb_io_slave_out;
|
|
||||||
-- for conversion from non-pipelined wishbone to pipelined
|
|
||||||
signal wb_sddma_stb_sent : std_ulogic;
|
|
||||||
|
|
||||||
-- Control/status
|
|
||||||
signal core_alt_reset : std_ulogic;
|
|
||||||
|
|
||||||
-- SPI flash
|
|
||||||
signal spi_sck : std_ulogic;
|
|
||||||
signal spi_cs_n : std_ulogic;
|
|
||||||
signal spi_sdat_o : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_oe : std_ulogic_vector(3 downto 0);
|
|
||||||
signal spi_sdat_i : std_ulogic_vector(3 downto 0);
|
|
||||||
|
|
||||||
-- ddram clock signals as vectors
|
|
||||||
signal ddram_clk_p_vec : std_ulogic_vector(0 downto 0);
|
|
||||||
signal ddram_clk_n_vec : std_ulogic_vector(0 downto 0);
|
|
||||||
|
|
||||||
-- Fixup various memory sizes based on generics
|
|
||||||
function get_bram_size return natural is
|
|
||||||
begin
|
|
||||||
if USE_LITEDRAM and NO_BRAM then
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return MEMORY_SIZE;
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
function get_payload_size return natural is
|
|
||||||
begin
|
|
||||||
if USE_LITEDRAM and NO_BRAM then
|
|
||||||
return MEMORY_SIZE;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
constant BRAM_SIZE : natural := get_bram_size;
|
|
||||||
constant PAYLOAD_SIZE : natural := get_payload_size;
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Main SoC
|
|
||||||
soc0: entity work.soc
|
|
||||||
generic map(
|
|
||||||
MEMORY_SIZE => BRAM_SIZE,
|
|
||||||
RAM_INIT_FILE => RAM_INIT_FILE,
|
|
||||||
SIM => false,
|
|
||||||
CLK_FREQ => CLK_FREQUENCY,
|
|
||||||
HAS_FPU => HAS_FPU,
|
|
||||||
HAS_BTC => HAS_BTC,
|
|
||||||
HAS_SHORT_MULT => HAS_SHORT_MULT,
|
|
||||||
HAS_DRAM => USE_LITEDRAM,
|
|
||||||
DRAM_SIZE => 256 * 1024 * 1024,
|
|
||||||
DRAM_INIT_SIZE => PAYLOAD_SIZE,
|
|
||||||
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,
|
|
||||||
HAS_LITEETH => USE_LITEETH,
|
|
||||||
UART0_IS_16550 => UART_IS_16550,
|
|
||||||
HAS_UART1 => HAS_UART1,
|
|
||||||
HAS_SD_CARD => USE_LITESDCARD,
|
|
||||||
HAS_GPIO => HAS_GPIO,
|
|
||||||
NGPIO => NGPIO
|
|
||||||
)
|
|
||||||
port map (
|
|
||||||
-- System signals
|
|
||||||
system_clk => system_clk,
|
|
||||||
rst => soc_rst,
|
|
||||||
|
|
||||||
-- UART signals
|
|
||||||
uart0_txd => uart_main_tx,
|
|
||||||
uart0_rxd => uart_main_rx,
|
|
||||||
|
|
||||||
-- SPI signals
|
|
||||||
spi_flash_sck => spi_sck,
|
|
||||||
spi_flash_cs_n => spi_cs_n,
|
|
||||||
spi_flash_sdat_o => spi_sdat_o,
|
|
||||||
spi_flash_sdat_oe => spi_sdat_oe,
|
|
||||||
spi_flash_sdat_i => spi_sdat_i,
|
|
||||||
|
|
||||||
-- External interrupts
|
|
||||||
ext_irq_eth => ext_irq_eth,
|
|
||||||
ext_irq_sdcard => ext_irq_sdcard,
|
|
||||||
|
|
||||||
-- DRAM wishbone
|
|
||||||
wb_dram_in => wb_dram_in,
|
|
||||||
wb_dram_out => wb_dram_out,
|
|
||||||
|
|
||||||
-- IO wishbone
|
|
||||||
wb_ext_io_in => wb_ext_io_in,
|
|
||||||
wb_ext_io_out => wb_ext_io_out,
|
|
||||||
wb_ext_is_dram_csr => wb_ext_is_dram_csr,
|
|
||||||
wb_ext_is_dram_init => wb_ext_is_dram_init,
|
|
||||||
wb_ext_is_eth => wb_ext_is_eth,
|
|
||||||
wb_ext_is_sdcard => wb_ext_is_sdcard,
|
|
||||||
|
|
||||||
-- DMA wishbone
|
|
||||||
wishbone_dma_in => wb_sddma_in,
|
|
||||||
wishbone_dma_out => wb_sddma_out,
|
|
||||||
|
|
||||||
alt_reset => core_alt_reset
|
|
||||||
);
|
|
||||||
|
|
||||||
-- SPI Flash
|
|
||||||
spi_flash_cs_n <= spi_cs_n;
|
|
||||||
spi_flash_mosi <= spi_sdat_o(0) when spi_sdat_oe(0) = '1' else 'Z';
|
|
||||||
spi_flash_miso <= spi_sdat_o(1) when spi_sdat_oe(1) = '1' else 'Z';
|
|
||||||
spi_flash_wp_n <= spi_sdat_o(2) when spi_sdat_oe(2) = '1' else 'Z';
|
|
||||||
spi_flash_hold_n <= spi_sdat_o(3) when spi_sdat_oe(3) = '1' else 'Z';
|
|
||||||
spi_sdat_i(0) <= spi_flash_mosi;
|
|
||||||
spi_sdat_i(1) <= spi_flash_miso;
|
|
||||||
spi_sdat_i(2) <= spi_flash_wp_n;
|
|
||||||
spi_sdat_i(3) <= spi_flash_hold_n;
|
|
||||||
|
|
||||||
STARTUPE2_INST: STARTUPE2
|
|
||||||
port map (
|
|
||||||
CLK => '0',
|
|
||||||
GSR => '0',
|
|
||||||
GTS => '0',
|
|
||||||
KEYCLEARB => '0',
|
|
||||||
PACK => '0',
|
|
||||||
USRCCLKO => spi_sck,
|
|
||||||
USRCCLKTS => '0',
|
|
||||||
USRDONEO => '1',
|
|
||||||
USRDONETS => '0'
|
|
||||||
);
|
|
||||||
|
|
||||||
nodram: if not USE_LITEDRAM generate
|
|
||||||
signal ddram_clk_dummy : std_ulogic;
|
|
||||||
begin
|
|
||||||
reset_controller: entity work.soc_reset
|
|
||||||
generic map(
|
|
||||||
RESET_LOW => RESET_LOW
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_clk => system_clk,
|
|
||||||
pll_locked_in => system_clk_locked,
|
|
||||||
ext_rst_in => ext_rst_n,
|
|
||||||
pll_rst_out => pll_rst,
|
|
||||||
rst_out => soc_rst
|
|
||||||
);
|
|
||||||
|
|
||||||
clkgen: entity work.clock_generator
|
|
||||||
generic map(
|
|
||||||
CLK_INPUT_HZ => 50000000,
|
|
||||||
CLK_OUTPUT_HZ => CLK_FREQUENCY
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_rst_in => pll_rst,
|
|
||||||
pll_clk_out => system_clk,
|
|
||||||
pll_locked_out => system_clk_locked
|
|
||||||
);
|
|
||||||
|
|
||||||
core_alt_reset <= '0';
|
|
||||||
|
|
||||||
-- Vivado barfs on those differential signals if left
|
|
||||||
-- unconnected. So instanciate a diff. buffer and feed
|
|
||||||
-- it a constant '0'.
|
|
||||||
dummy_dram_clk: OBUFDS
|
|
||||||
port map (
|
|
||||||
O => ddram_clk_p,
|
|
||||||
OB => ddram_clk_n,
|
|
||||||
I => ddram_clk_dummy
|
|
||||||
);
|
|
||||||
ddram_clk_dummy <= '0';
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
has_dram: if USE_LITEDRAM generate
|
|
||||||
signal dram_init_done : std_ulogic;
|
|
||||||
signal dram_init_error : std_ulogic;
|
|
||||||
signal dram_sys_rst : std_ulogic;
|
|
||||||
signal rst_gen_rst : std_ulogic;
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- Eventually dig out the frequency from the generator
|
|
||||||
-- but for now, assert it's 100Mhz
|
|
||||||
assert CLK_FREQUENCY = 100000000;
|
|
||||||
|
|
||||||
reset_controller: entity work.soc_reset
|
|
||||||
generic map(
|
|
||||||
RESET_LOW => RESET_LOW,
|
|
||||||
PLL_RESET_BITS => 18,
|
|
||||||
SOC_RESET_BITS => 1
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
ext_clk => ext_clk,
|
|
||||||
pll_clk => system_clk,
|
|
||||||
pll_locked_in => system_clk_locked,
|
|
||||||
ext_rst_in => ext_rst_n,
|
|
||||||
pll_rst_out => pll_rst,
|
|
||||||
rst_out => rst_gen_rst
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Generate SoC reset
|
|
||||||
soc_rst_gen: process(system_clk)
|
|
||||||
begin
|
|
||||||
if ext_rst_n = '0' then
|
|
||||||
soc_rst <= '1';
|
|
||||||
elsif rising_edge(system_clk) then
|
|
||||||
soc_rst <= dram_sys_rst or not system_clk_locked;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
ddram_clk_p_vec <= (others => ddram_clk_p);
|
|
||||||
ddram_clk_n_vec <= (others => ddram_clk_n);
|
|
||||||
|
|
||||||
dram: entity work.litedram_wrapper
|
|
||||||
generic map(
|
|
||||||
DRAM_ABITS => 24,
|
|
||||||
DRAM_ALINES => 14,
|
|
||||||
DRAM_DLINES => 16,
|
|
||||||
DRAM_CKLINES => 1,
|
|
||||||
DRAM_PORT_WIDTH => 128,
|
|
||||||
PAYLOAD_FILE => RAM_INIT_FILE,
|
|
||||||
PAYLOAD_SIZE => PAYLOAD_SIZE
|
|
||||||
)
|
|
||||||
port map(
|
|
||||||
clk_in => ext_clk,
|
|
||||||
rst => pll_rst,
|
|
||||||
system_clk => system_clk,
|
|
||||||
system_reset => dram_sys_rst,
|
|
||||||
core_alt_reset => core_alt_reset,
|
|
||||||
pll_locked => system_clk_locked,
|
|
||||||
|
|
||||||
wb_in => wb_dram_in,
|
|
||||||
wb_out => wb_dram_out,
|
|
||||||
wb_ctrl_in => wb_ext_io_in,
|
|
||||||
wb_ctrl_out => wb_dram_ctrl_out,
|
|
||||||
wb_ctrl_is_csr => wb_ext_is_dram_csr,
|
|
||||||
wb_ctrl_is_init => wb_ext_is_dram_init,
|
|
||||||
|
|
||||||
init_done => dram_init_done,
|
|
||||||
init_error => dram_init_error,
|
|
||||||
|
|
||||||
ddram_a => ddram_a,
|
|
||||||
ddram_ba => ddram_ba,
|
|
||||||
ddram_ras_n => ddram_ras_n,
|
|
||||||
ddram_cas_n => ddram_cas_n,
|
|
||||||
ddram_we_n => ddram_we_n,
|
|
||||||
ddram_cs_n => open,
|
|
||||||
ddram_dm => ddram_dm,
|
|
||||||
ddram_dq => ddram_dq,
|
|
||||||
ddram_dqs_p => ddram_dqs_p,
|
|
||||||
ddram_dqs_n => ddram_dqs_n,
|
|
||||||
ddram_clk_p => ddram_clk_p_vec,
|
|
||||||
ddram_clk_n => ddram_clk_n_vec,
|
|
||||||
ddram_cke => ddram_cke,
|
|
||||||
ddram_odt => ddram_odt,
|
|
||||||
ddram_reset_n => ddram_reset_n
|
|
||||||
);
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
has_liteeth : if USE_LITEETH generate
|
|
||||||
|
|
||||||
component liteeth_core port (
|
|
||||||
sys_clock : in std_ulogic;
|
|
||||||
sys_reset : in std_ulogic;
|
|
||||||
gmii_eth_clocks_tx : in std_ulogic;
|
|
||||||
gmii_eth_clocks_gtx : out std_ulogic;
|
|
||||||
gmii_eth_clocks_rx : in std_ulogic;
|
|
||||||
gmii_eth_rst_n : out std_ulogic;
|
|
||||||
gmii_eth_mdio : inout std_ulogic;
|
|
||||||
gmii_eth_mdc : out std_ulogic;
|
|
||||||
gmii_eth_rx_dv : in std_ulogic;
|
|
||||||
gmii_eth_rx_er : in std_ulogic;
|
|
||||||
gmii_eth_rx_data : in std_ulogic_vector(7 downto 0);
|
|
||||||
gmii_eth_tx_en : out std_ulogic;
|
|
||||||
gmii_eth_tx_er : out std_ulogic;
|
|
||||||
gmii_eth_tx_data : out std_ulogic_vector(7 downto 0);
|
|
||||||
gmii_eth_col : in std_ulogic;
|
|
||||||
gmii_eth_crs : in std_ulogic;
|
|
||||||
wishbone_adr : in std_ulogic_vector(29 downto 0);
|
|
||||||
wishbone_dat_w : in std_ulogic_vector(31 downto 0);
|
|
||||||
wishbone_dat_r : out std_ulogic_vector(31 downto 0);
|
|
||||||
wishbone_sel : in std_ulogic_vector(3 downto 0);
|
|
||||||
wishbone_cyc : in std_ulogic;
|
|
||||||
wishbone_stb : in std_ulogic;
|
|
||||||
wishbone_ack : out std_ulogic;
|
|
||||||
wishbone_we : in std_ulogic;
|
|
||||||
wishbone_cti : in std_ulogic_vector(2 downto 0);
|
|
||||||
wishbone_bte : in std_ulogic_vector(1 downto 0);
|
|
||||||
wishbone_err : out std_ulogic;
|
|
||||||
interrupt : out std_ulogic
|
|
||||||
);
|
|
||||||
end component;
|
|
||||||
|
|
||||||
signal wb_eth_cyc : std_ulogic;
|
|
||||||
signal wb_eth_adr : std_ulogic_vector(29 downto 0);
|
|
||||||
|
|
||||||
-- Change this to use a PLL instead of a BUFR to generate the 25Mhz
|
|
||||||
-- reference clock to the PHY.
|
|
||||||
constant USE_PLL : boolean := false;
|
|
||||||
begin
|
|
||||||
liteeth : liteeth_core
|
|
||||||
port map(
|
|
||||||
sys_clock => system_clk,
|
|
||||||
sys_reset => soc_rst,
|
|
||||||
gmii_eth_clocks_tx => eth_clocks_tx,
|
|
||||||
gmii_eth_clocks_gtx => eth_clocks_gtx,
|
|
||||||
gmii_eth_clocks_rx => eth_clocks_rx,
|
|
||||||
gmii_eth_rst_n => eth_rst_n,
|
|
||||||
gmii_eth_mdio => eth_mdio,
|
|
||||||
gmii_eth_mdc => eth_mdc,
|
|
||||||
gmii_eth_rx_dv => eth_rx_dv,
|
|
||||||
gmii_eth_rx_er => eth_rx_er,
|
|
||||||
gmii_eth_rx_data => eth_rx_data,
|
|
||||||
gmii_eth_tx_en => eth_tx_en,
|
|
||||||
gmii_eth_tx_er => eth_tx_er,
|
|
||||||
gmii_eth_tx_data => eth_tx_data,
|
|
||||||
gmii_eth_col => eth_col,
|
|
||||||
gmii_eth_crs => eth_crs,
|
|
||||||
wishbone_adr => wb_eth_adr,
|
|
||||||
wishbone_dat_w => wb_ext_io_in.dat,
|
|
||||||
wishbone_dat_r => wb_eth_out.dat,
|
|
||||||
wishbone_sel => wb_ext_io_in.sel,
|
|
||||||
wishbone_cyc => wb_eth_cyc,
|
|
||||||
wishbone_stb => wb_ext_io_in.stb,
|
|
||||||
wishbone_ack => wb_eth_out.ack,
|
|
||||||
wishbone_we => wb_ext_io_in.we,
|
|
||||||
wishbone_cti => "000",
|
|
||||||
wishbone_bte => "00",
|
|
||||||
wishbone_err => open,
|
|
||||||
interrupt => ext_irq_eth
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Gate cyc with "chip select" from soc
|
|
||||||
wb_eth_cyc <= wb_ext_io_in.cyc and wb_ext_is_eth;
|
|
||||||
|
|
||||||
-- Remove top address bits as liteeth decoder doesn't know about them
|
|
||||||
wb_eth_adr <= x"000" & "000" & wb_ext_io_in.adr(14 downto 0);
|
|
||||||
|
|
||||||
-- LiteETH isn't pipelined
|
|
||||||
wb_eth_out.stall <= not wb_eth_out.ack;
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
no_liteeth : if not USE_LITEETH generate
|
|
||||||
ext_irq_eth <= '0';
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
-- SD card pmod
|
|
||||||
has_sdcard : if USE_LITESDCARD generate
|
|
||||||
component litesdcard_core port (
|
|
||||||
clk : in std_ulogic;
|
|
||||||
rst : in std_ulogic;
|
|
||||||
-- wishbone for accessing control registers
|
|
||||||
wb_ctrl_adr : in std_ulogic_vector(29 downto 0);
|
|
||||||
wb_ctrl_dat_w : in std_ulogic_vector(31 downto 0);
|
|
||||||
wb_ctrl_dat_r : out std_ulogic_vector(31 downto 0);
|
|
||||||
wb_ctrl_sel : in std_ulogic_vector(3 downto 0);
|
|
||||||
wb_ctrl_cyc : in std_ulogic;
|
|
||||||
wb_ctrl_stb : in std_ulogic;
|
|
||||||
wb_ctrl_ack : out std_ulogic;
|
|
||||||
wb_ctrl_we : in std_ulogic;
|
|
||||||
wb_ctrl_cti : in std_ulogic_vector(2 downto 0);
|
|
||||||
wb_ctrl_bte : in std_ulogic_vector(1 downto 0);
|
|
||||||
wb_ctrl_err : out std_ulogic;
|
|
||||||
-- wishbone for SD card core to use for DMA
|
|
||||||
wb_dma_adr : out std_ulogic_vector(29 downto 0);
|
|
||||||
wb_dma_dat_w : out std_ulogic_vector(31 downto 0);
|
|
||||||
wb_dma_dat_r : in std_ulogic_vector(31 downto 0);
|
|
||||||
wb_dma_sel : out std_ulogic_vector(3 downto 0);
|
|
||||||
wb_dma_cyc : out std_ulogic;
|
|
||||||
wb_dma_stb : out std_ulogic;
|
|
||||||
wb_dma_ack : in std_ulogic;
|
|
||||||
wb_dma_we : out std_ulogic;
|
|
||||||
wb_dma_cti : out std_ulogic_vector(2 downto 0);
|
|
||||||
wb_dma_bte : out std_ulogic_vector(1 downto 0);
|
|
||||||
wb_dma_err : in std_ulogic;
|
|
||||||
-- connections to SD card
|
|
||||||
sdcard_data : inout std_ulogic_vector(3 downto 0);
|
|
||||||
sdcard_cmd : inout std_ulogic;
|
|
||||||
sdcard_clk : out std_ulogic;
|
|
||||||
sdcard_cd : in std_ulogic;
|
|
||||||
irq : out std_ulogic
|
|
||||||
);
|
|
||||||
end component;
|
|
||||||
|
|
||||||
signal wb_sdcard_cyc : std_ulogic;
|
|
||||||
signal wb_sdcard_adr : std_ulogic_vector(29 downto 0);
|
|
||||||
|
|
||||||
begin
|
|
||||||
litesdcard : litesdcard_core
|
|
||||||
port map (
|
|
||||||
clk => system_clk,
|
|
||||||
rst => soc_rst,
|
|
||||||
wb_ctrl_adr => wb_sdcard_adr,
|
|
||||||
wb_ctrl_dat_w => wb_ext_io_in.dat,
|
|
||||||
wb_ctrl_dat_r => wb_sdcard_out.dat,
|
|
||||||
wb_ctrl_sel => wb_ext_io_in.sel,
|
|
||||||
wb_ctrl_cyc => wb_sdcard_cyc,
|
|
||||||
wb_ctrl_stb => wb_ext_io_in.stb,
|
|
||||||
wb_ctrl_ack => wb_sdcard_out.ack,
|
|
||||||
wb_ctrl_we => wb_ext_io_in.we,
|
|
||||||
wb_ctrl_cti => "000",
|
|
||||||
wb_ctrl_bte => "00",
|
|
||||||
wb_ctrl_err => open,
|
|
||||||
wb_dma_adr => wb_sddma_nr.adr,
|
|
||||||
wb_dma_dat_w => wb_sddma_nr.dat,
|
|
||||||
wb_dma_dat_r => wb_sddma_ir.dat,
|
|
||||||
wb_dma_sel => wb_sddma_nr.sel,
|
|
||||||
wb_dma_cyc => wb_sddma_nr.cyc,
|
|
||||||
wb_dma_stb => wb_sddma_nr.stb,
|
|
||||||
wb_dma_ack => wb_sddma_ir.ack,
|
|
||||||
wb_dma_we => wb_sddma_nr.we,
|
|
||||||
wb_dma_cti => open,
|
|
||||||
wb_dma_bte => open,
|
|
||||||
wb_dma_err => '0',
|
|
||||||
sdcard_data => sdcard_data,
|
|
||||||
sdcard_cmd => sdcard_cmd,
|
|
||||||
sdcard_clk => sdcard_clk,
|
|
||||||
sdcard_cd => sdcard_cd,
|
|
||||||
irq => ext_irq_sdcard
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Gate cyc with chip select from SoC
|
|
||||||
wb_sdcard_cyc <= wb_ext_io_in.cyc and wb_ext_is_sdcard;
|
|
||||||
|
|
||||||
wb_sdcard_adr <= x"0000" & wb_ext_io_in.adr(13 downto 0);
|
|
||||||
|
|
||||||
wb_sdcard_out.stall <= not wb_sdcard_out.ack;
|
|
||||||
|
|
||||||
-- Convert non-pipelined DMA wishbone to pipelined by suppressing
|
|
||||||
-- non-acknowledged strobes
|
|
||||||
process(system_clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(system_clk) then
|
|
||||||
wb_sddma_out <= wb_sddma_nr;
|
|
||||||
if wb_sddma_stb_sent = '1' or
|
|
||||||
(wb_sddma_out.stb = '1' and wb_sddma_in.stall = '0') then
|
|
||||||
wb_sddma_out.stb <= '0';
|
|
||||||
end if;
|
|
||||||
if wb_sddma_nr.cyc = '0' or wb_sddma_ir.ack = '1' then
|
|
||||||
wb_sddma_stb_sent <= '0';
|
|
||||||
elsif wb_sddma_in.stall = '0' then
|
|
||||||
wb_sddma_stb_sent <= wb_sddma_nr.stb;
|
|
||||||
end if;
|
|
||||||
wb_sddma_ir <= wb_sddma_in;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end generate;
|
|
||||||
|
|
||||||
-- Mux WB response on the IO bus
|
|
||||||
wb_ext_io_out <= wb_eth_out when wb_ext_is_eth = '1' else
|
|
||||||
wb_sdcard_out when wb_ext_is_sdcard = '1' else
|
|
||||||
wb_dram_ctrl_out;
|
|
||||||
|
|
||||||
led0_n <= system_clk_locked;
|
|
||||||
led1_n <= not soc_rst;
|
|
||||||
|
|
||||||
end architecture behaviour;
|
|
@ -1,487 +0,0 @@
|
|||||||
################################################################################
|
|
||||||
# clkin, reset, uart pins...
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN M21 IOSTANDARD LVCMOS33 } [get_ports { ext_clk }];
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN H7 IOSTANDARD LVCMOS33 } [get_ports { ext_rst_n }];
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports { uart_main_tx }];
|
|
||||||
set_property -dict { PACKAGE_PIN F3 IOSTANDARD LVCMOS33 } [get_ports { uart_main_rx }];
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# LEDs
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN V16 IOSTANDARD LVCMOS33 } [get_ports { led0_n }];
|
|
||||||
set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { led1_n }];
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# SPI Flash
|
|
||||||
################################################################################ema
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_cs_n }];
|
|
||||||
set_property -dict { PACKAGE_PIN R14 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_mosi }];
|
|
||||||
set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_miso }];
|
|
||||||
set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_wp_n }];
|
|
||||||
set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports { spi_flash_hold_n }];
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Micro SD
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
set_property -dict { PACKAGE_PIN M5 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_data[0] }];
|
|
||||||
set_property -dict { PACKAGE_PIN M7 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_data[1] }];
|
|
||||||
set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_data[2] }];
|
|
||||||
set_property -dict { PACKAGE_PIN J6 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_data[3] }];
|
|
||||||
set_property -dict { PACKAGE_PIN J8 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_cmd }];
|
|
||||||
set_property -dict { PACKAGE_PIN L4 IOSTANDARD LVCMOS33 SLEW FAST } [get_ports { sdcard_clk }];
|
|
||||||
set_property -dict { PACKAGE_PIN N6 IOSTANDARD LVCMOS33 } [get_ports { sdcard_cd }];
|
|
||||||
|
|
||||||
# Put registers into IOBs to improve timing
|
|
||||||
set_property IOB true [get_cells -hierarchical -filter {NAME =~*.litesdcard/sdcard_*}]
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# PMOD header J10 (high-speed, no protection resisters)
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
#set_property -dict { PACKAGE_PIN D5 IOSTANDARD LVCMOS33 } [get_ports { pmod_j10_1 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN G5 IOSTANDARD LVCMOS33 } [get_ports { pmod_j10_2 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN G7 IOSTANDARD LVCMOS33 } [get_ports { pmod_j10_3 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN G8 IOSTANDARD LVCMOS33 } [get_ports { pmod_j10_4 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN E5 IOSTANDARD LVCMOS33 } [get_ports { pmod_j10_7 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN E6 IOSTANDARD LVCMOS33 } [get_ports { pmod_j10_8 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN D6 IOSTANDARD LVCMOS33 } [get_ports { pmod_j10_9 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN G6 IOSTANDARD LVCMOS33 } [get_ports { pmod_j10_10 }];
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# PMOD header J11 (high-speed, no protection resisters)
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
#set_property -dict { PACKAGE_PIN H4 IOSTANDARD LVCMOS33 } [get_ports { pmod_j11_1 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN F4 IOSTANDARD LVCMOS33 } [get_ports { pmod_j11_2 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN A4 IOSTANDARD LVCMOS33 } [get_ports { pmod_j11_3 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN A5 IOSTANDARD LVCMOS33 } [get_ports { pmod_j11_4 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN J4 IOSTANDARD LVCMOS33 } [get_ports { pmod_j11_7 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN G4 IOSTANDARD LVCMOS33 } [get_ports { pmod_j11_8 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN B4 IOSTANDARD LVCMOS33 } [get_ports { pmod_j11_9 }];
|
|
||||||
#set_property -dict { PACKAGE_PIN B5 IOSTANDARD LVCMOS33 } [get_ports { pmod_j11_10 }];
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# HDR 20X2 connector
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
## TODO
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Ethernet (generated by LiteX)
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
# eth_clocks:0.tx
|
|
||||||
set_property LOC M2 [get_ports {eth_clocks_tx}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_clocks_tx}]
|
|
||||||
|
|
||||||
# eth_clocks:0.gtx
|
|
||||||
set_property LOC U1 [get_ports {eth_clocks_gtx}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_clocks_gtx}]
|
|
||||||
|
|
||||||
# eth_clocks:0.rx
|
|
||||||
set_property LOC P4 [get_ports {eth_clocks_rx}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_clocks_rx}]
|
|
||||||
|
|
||||||
# eth:0.rst_n
|
|
||||||
set_property LOC R1 [get_ports {eth_rst_n}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rst_n}]
|
|
||||||
|
|
||||||
# eth:0.mdio
|
|
||||||
set_property LOC H1 [get_ports {eth_mdio}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_mdio}]
|
|
||||||
|
|
||||||
# eth:0.mdc
|
|
||||||
set_property LOC H2 [get_ports {eth_mdc}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_mdc}]
|
|
||||||
|
|
||||||
# eth:0.rx_dv
|
|
||||||
set_property LOC L3 [get_ports {eth_rx_dv}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_dv}]
|
|
||||||
|
|
||||||
# eth:0.rx_er
|
|
||||||
set_property LOC U5 [get_ports {eth_rx_er}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_er}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC M4 [get_ports {eth_rx_data[0]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[0]}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC N3 [get_ports {eth_rx_data[1]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[1]}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC N4 [get_ports {eth_rx_data[2]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[2]}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC P3 [get_ports {eth_rx_data[3]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[3]}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC R3 [get_ports {eth_rx_data[4]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[4]}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC T3 [get_ports {eth_rx_data[5]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[5]}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC T4 [get_ports {eth_rx_data[6]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[6]}]
|
|
||||||
|
|
||||||
# eth:0.rx_data
|
|
||||||
set_property LOC T5 [get_ports {eth_rx_data[7]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_rx_data[7]}]
|
|
||||||
|
|
||||||
# eth:0.tx_en
|
|
||||||
set_property LOC T2 [get_ports {eth_tx_en}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_en}]
|
|
||||||
|
|
||||||
# eth:0.tx_er
|
|
||||||
set_property LOC J1 [get_ports {eth_tx_er}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_er}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC R2 [get_ports {eth_tx_data[0]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[0]}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC P1 [get_ports {eth_tx_data[1]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[1]}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC N2 [get_ports {eth_tx_data[2]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[2]}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC N1 [get_ports {eth_tx_data[3]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[3]}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC M1 [get_ports {eth_tx_data[4]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[4]}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC L2 [get_ports {eth_tx_data[5]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[5]}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC K2 [get_ports {eth_tx_data[6]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[6]}]
|
|
||||||
|
|
||||||
# eth:0.tx_data
|
|
||||||
set_property LOC K1 [get_ports {eth_tx_data[7]}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_tx_data[7]}]
|
|
||||||
|
|
||||||
# eth:0.col
|
|
||||||
set_property LOC U4 [get_ports {eth_col}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_col}]
|
|
||||||
|
|
||||||
# eth:0.crs
|
|
||||||
set_property LOC U2 [get_ports {eth_crs}]
|
|
||||||
set_property IOSTANDARD LVCMOS33 [get_ports {eth_crs}]
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# DRAM (generated by LiteX)
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC E17 [get_ports {ddram_a[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[0]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[0]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC G17 [get_ports {ddram_a[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[1]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[1]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC F17 [get_ports {ddram_a[2]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[2]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[2]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC C17 [get_ports {ddram_a[3]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[3]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[3]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC G16 [get_ports {ddram_a[4]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[4]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[4]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC D16 [get_ports {ddram_a[5]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[5]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[5]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC H16 [get_ports {ddram_a[6]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[6]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[6]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC E16 [get_ports {ddram_a[7]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[7]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[7]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC H14 [get_ports {ddram_a[8]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[8]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[8]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC F15 [get_ports {ddram_a[9]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[9]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[9]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC F20 [get_ports {ddram_a[10]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[10]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[10]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC H15 [get_ports {ddram_a[11]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[11]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[11]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC C18 [get_ports {ddram_a[12]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[12]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[12]}]
|
|
||||||
|
|
||||||
# ddram:0.a
|
|
||||||
set_property LOC G15 [get_ports {ddram_a[13]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_a[13]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_a[13]}]
|
|
||||||
|
|
||||||
# ddram:0.ba
|
|
||||||
set_property LOC B17 [get_ports {ddram_ba[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ba[0]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_ba[0]}]
|
|
||||||
|
|
||||||
# ddram:0.ba
|
|
||||||
set_property LOC D18 [get_ports {ddram_ba[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ba[1]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_ba[1]}]
|
|
||||||
|
|
||||||
# ddram:0.ba
|
|
||||||
set_property LOC A17 [get_ports {ddram_ba[2]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ba[2]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_ba[2]}]
|
|
||||||
|
|
||||||
# ddram:0.ras_n
|
|
||||||
set_property LOC A19 [get_ports {ddram_ras_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_ras_n}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_ras_n}]
|
|
||||||
|
|
||||||
# ddram:0.cas_n
|
|
||||||
set_property LOC B19 [get_ports {ddram_cas_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_cas_n}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_cas_n}]
|
|
||||||
|
|
||||||
# ddram:0.we_n
|
|
||||||
set_property LOC A18 [get_ports {ddram_we_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_we_n}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_we_n}]
|
|
||||||
|
|
||||||
# ddram:0.dm
|
|
||||||
set_property LOC A22 [get_ports {ddram_dm[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dm[0]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dm[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dm
|
|
||||||
set_property LOC C22 [get_ports {ddram_dm[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dm[1]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dm[1]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC D21 [get_ports {ddram_dq[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[0]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[0]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC C21 [get_ports {ddram_dq[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[1]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[1]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[1]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC B22 [get_ports {ddram_dq[2]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[2]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[2]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[2]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC B21 [get_ports {ddram_dq[3]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[3]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[3]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[3]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC D19 [get_ports {ddram_dq[4]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[4]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[4]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[4]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC E20 [get_ports {ddram_dq[5]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[5]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[5]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[5]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC C19 [get_ports {ddram_dq[6]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[6]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[6]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[6]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC D20 [get_ports {ddram_dq[7]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[7]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[7]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[7]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC C23 [get_ports {ddram_dq[8]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[8]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[8]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[8]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC D23 [get_ports {ddram_dq[9]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[9]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[9]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[9]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC B24 [get_ports {ddram_dq[10]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[10]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[10]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[10]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC B25 [get_ports {ddram_dq[11]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[11]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[11]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[11]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC C24 [get_ports {ddram_dq[12]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[12]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[12]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[12]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC C26 [get_ports {ddram_dq[13]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[13]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[13]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[13]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC A25 [get_ports {ddram_dq[14]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[14]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[14]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[14]}]
|
|
||||||
|
|
||||||
# ddram:0.dq
|
|
||||||
set_property LOC B26 [get_ports {ddram_dq[15]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dq[15]}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_dq[15]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dq[15]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_p
|
|
||||||
set_property LOC B20 [get_ports {ddram_dqs_p[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_p[0]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_dqs_p[0]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dqs_p[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_p
|
|
||||||
set_property LOC A23 [get_ports {ddram_dqs_p[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_p[1]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_dqs_p[1]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dqs_p[1]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_n
|
|
||||||
set_property LOC A20 [get_ports {ddram_dqs_n[0]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_n[0]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_dqs_n[0]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dqs_n[0]}]
|
|
||||||
|
|
||||||
# ddram:0.dqs_n
|
|
||||||
set_property LOC A24 [get_ports {ddram_dqs_n[1]}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_dqs_n[1]}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_dqs_n[1]}]
|
|
||||||
set_property IN_TERM UNTUNED_SPLIT_40 [get_ports {ddram_dqs_n[1]}]
|
|
||||||
|
|
||||||
# ddram:0.clk_p
|
|
||||||
set_property LOC F18 [get_ports {ddram_clk_p}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_clk_p}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_clk_p}]
|
|
||||||
|
|
||||||
# ddram:0.clk_n
|
|
||||||
set_property LOC F19 [get_ports {ddram_clk_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_clk_n}]
|
|
||||||
set_property IOSTANDARD DIFF_SSTL135 [get_ports {ddram_clk_n}]
|
|
||||||
|
|
||||||
# ddram:0.cke
|
|
||||||
set_property LOC E18 [get_ports {ddram_cke}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_cke}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_cke}]
|
|
||||||
|
|
||||||
# ddram:0.odt
|
|
||||||
set_property LOC G19 [get_ports {ddram_odt}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_odt}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_odt}]
|
|
||||||
|
|
||||||
# ddram:0.reset_n
|
|
||||||
set_property LOC H17 [get_ports {ddram_reset_n}]
|
|
||||||
set_property SLEW FAST [get_ports {ddram_reset_n}]
|
|
||||||
set_property IOSTANDARD SSTL135 [get_ports {ddram_reset_n}]
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Design constraints and bitsteam attributes
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
set_property INTERNAL_VREF 0.675 [get_iobanks 16]
|
|
||||||
|
|
||||||
set_property CONFIG_VOLTAGE 3.3 [current_design]
|
|
||||||
set_property CFGBVS VCCO [current_design]
|
|
||||||
|
|
||||||
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
|
|
||||||
set_property BITSTREAM.CONFIG.CONFIGRATE 33 [current_design]
|
|
||||||
set_property CONFIG_MODE SPIx4 [current_design]
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Clock constraints
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
create_clock -name sys_clk_pin -period 20.00 [get_ports { ext_clk }];
|
|
||||||
|
|
||||||
create_clock -name eth_rx_clk -period 8.0 [get_nets has_liteeth.liteeth/eth_rx_clk]
|
|
||||||
create_clock -name eth_tx_clk -period 8.0 [get_nets has_liteeth.liteeth/eth_tx_clk]
|
|
||||||
|
|
||||||
set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets has_liteeth.liteeth/sys_clk]] -group [get_clocks -include_generated_clocks -of [get_nets has_liteeth.liteeth/eth_rx_clk]] -asynchronous
|
|
||||||
|
|
||||||
set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets has_liteeth.liteeth/sys_clk]] -group [get_clocks -include_generated_clocks -of [get_nets has_liteeth.liteeth/eth_tx_clk]] -asynchronous
|
|
||||||
|
|
||||||
set_clock_groups -group [get_clocks -include_generated_clocks -of [get_nets has_liteeth.liteeth/eth_rx_clk]] -group [get_clocks -include_generated_clocks -of [get_nets has_liteeth.liteeth/eth_tx_clk]] -asynchronous
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# False path constraints (from LiteX as they relate to LiteDRAM and LiteEth)
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
set_false_path -quiet -through [get_nets -hierarchical -filter {mr_ff == TRUE}]
|
|
||||||
|
|
||||||
set_false_path -quiet -to [get_pins -filter {REF_PIN_NAME == PRE} -of_objects [get_cells -hierarchical -filter {ars_ff1 == TRUE || ars_ff2 == TRUE}]]
|
|
||||||
|
|
||||||
set_max_delay 2 -quiet -from [get_pins -filter {REF_PIN_NAME == C} -of_objects [get_cells -hierarchical -filter {ars_ff1 == TRUE}]] -to [get_pins -filter {REF_PIN_NAME == D} -of_objects [get_cells -hierarchical -filter {ars_ff2 == TRUE}]]
|
|
@ -1,99 +0,0 @@
|
|||||||
-- GPIO module for microwatt
|
|
||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
|
|
||||||
entity gpio is
|
|
||||||
generic (
|
|
||||||
NGPIO : integer := 32
|
|
||||||
);
|
|
||||||
port (
|
|
||||||
clk : in std_ulogic;
|
|
||||||
rst : in std_ulogic;
|
|
||||||
|
|
||||||
-- Wishbone
|
|
||||||
wb_in : in wb_io_master_out;
|
|
||||||
wb_out : out wb_io_slave_out;
|
|
||||||
|
|
||||||
-- GPIO lines
|
|
||||||
gpio_in : in std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
gpio_out : out std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
-- 1 = output, 0 = input
|
|
||||||
gpio_dir : out std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
|
|
||||||
-- Interrupt
|
|
||||||
intr : out std_ulogic
|
|
||||||
);
|
|
||||||
end entity gpio;
|
|
||||||
|
|
||||||
architecture behaviour of gpio is
|
|
||||||
constant GPIO_REG_BITS : positive := 5;
|
|
||||||
|
|
||||||
-- Register addresses, matching addr downto 2, so 4 bytes per reg
|
|
||||||
constant GPIO_REG_DATA_OUT : std_ulogic_vector(GPIO_REG_BITS-1 downto 0) := "00000";
|
|
||||||
constant GPIO_REG_DATA_IN : std_ulogic_vector(GPIO_REG_BITS-1 downto 0) := "00001";
|
|
||||||
constant GPIO_REG_DIR : std_ulogic_vector(GPIO_REG_BITS-1 downto 0) := "00010";
|
|
||||||
constant GPIO_REG_DATA_SET : std_ulogic_vector(GPIO_REG_BITS-1 downto 0) := "00100";
|
|
||||||
constant GPIO_REG_DATA_CLR : std_ulogic_vector(GPIO_REG_BITS-1 downto 0) := "00101";
|
|
||||||
|
|
||||||
-- Current output value and direction
|
|
||||||
signal reg_data : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
signal reg_dirn : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
signal reg_in1 : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
signal reg_in2 : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
|
|
||||||
signal wb_rsp : wb_io_slave_out;
|
|
||||||
signal reg_out : std_ulogic_vector(NGPIO - 1 downto 0);
|
|
||||||
|
|
||||||
begin
|
|
||||||
|
|
||||||
-- No interrupt facility for now
|
|
||||||
intr <= '0';
|
|
||||||
|
|
||||||
gpio_out <= reg_data;
|
|
||||||
gpio_dir <= reg_dirn;
|
|
||||||
|
|
||||||
-- Wishbone response
|
|
||||||
wb_rsp.ack <= wb_in.cyc and wb_in.stb;
|
|
||||||
with wb_in.adr(GPIO_REG_BITS - 1 downto 0) select reg_out <=
|
|
||||||
reg_data when GPIO_REG_DATA_OUT,
|
|
||||||
reg_in2 when GPIO_REG_DATA_IN,
|
|
||||||
reg_dirn when GPIO_REG_DIR,
|
|
||||||
(others => '0') when others;
|
|
||||||
wb_rsp.dat(wb_rsp.dat'left downto NGPIO) <= (others => '0');
|
|
||||||
wb_rsp.dat(NGPIO - 1 downto 0) <= reg_out;
|
|
||||||
wb_rsp.stall <= '0';
|
|
||||||
|
|
||||||
regs_rw: process(clk)
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
wb_out <= wb_rsp;
|
|
||||||
reg_in2 <= reg_in1;
|
|
||||||
reg_in1 <= gpio_in;
|
|
||||||
if rst = '1' then
|
|
||||||
reg_data <= (others => '0');
|
|
||||||
reg_dirn <= (others => '0');
|
|
||||||
wb_out.ack <= '0';
|
|
||||||
else
|
|
||||||
if wb_in.cyc = '1' and wb_in.stb = '1' and wb_in.we = '1' then
|
|
||||||
case wb_in.adr(GPIO_REG_BITS - 1 downto 0) is
|
|
||||||
when GPIO_REG_DATA_OUT =>
|
|
||||||
reg_data <= wb_in.dat(NGPIO - 1 downto 0);
|
|
||||||
when GPIO_REG_DIR =>
|
|
||||||
reg_dirn <= wb_in.dat(NGPIO - 1 downto 0);
|
|
||||||
when GPIO_REG_DATA_SET =>
|
|
||||||
reg_data <= reg_data or wb_in.dat(NGPIO - 1 downto 0);
|
|
||||||
when GPIO_REG_DATA_CLR =>
|
|
||||||
reg_data <= reg_data and not wb_in.dat(NGPIO - 1 downto 0);
|
|
||||||
when others =>
|
|
||||||
end case;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
end architecture behaviour;
|
|
||||||
|
|
@ -0,0 +1,107 @@
|
|||||||
|
library ieee;
|
||||||
|
use ieee.std_logic_1164.all;
|
||||||
|
use ieee.numeric_std.all;
|
||||||
|
|
||||||
|
library work;
|
||||||
|
use work.common.all;
|
||||||
|
|
||||||
|
entity gpr_hazard is
|
||||||
|
generic (
|
||||||
|
PIPELINE_DEPTH : natural := 1
|
||||||
|
);
|
||||||
|
port(
|
||||||
|
clk : in std_ulogic;
|
||||||
|
busy_in : in std_ulogic;
|
||||||
|
deferred : in std_ulogic;
|
||||||
|
complete_in : in std_ulogic;
|
||||||
|
flush_in : in std_ulogic;
|
||||||
|
issuing : in std_ulogic;
|
||||||
|
|
||||||
|
gpr_write_valid_in : in std_ulogic;
|
||||||
|
gpr_write_in : in gspr_index_t;
|
||||||
|
bypass_avail : in std_ulogic;
|
||||||
|
gpr_read_valid_in : in std_ulogic;
|
||||||
|
gpr_read_in : in gspr_index_t;
|
||||||
|
|
||||||
|
ugpr_write_valid : in std_ulogic;
|
||||||
|
ugpr_write_reg : in gspr_index_t;
|
||||||
|
|
||||||
|
stall_out : out std_ulogic;
|
||||||
|
use_bypass : out std_ulogic
|
||||||
|
);
|
||||||
|
end entity gpr_hazard;
|
||||||
|
architecture behaviour of gpr_hazard is
|
||||||
|
type pipeline_entry_type is record
|
||||||
|
valid : std_ulogic;
|
||||||
|
bypass : std_ulogic;
|
||||||
|
gpr : gspr_index_t;
|
||||||
|
ugpr_valid : std_ulogic;
|
||||||
|
ugpr : gspr_index_t;
|
||||||
|
end record;
|
||||||
|
constant pipeline_entry_init : pipeline_entry_type := (valid => '0', bypass => '0', gpr => (others => '0'),
|
||||||
|
ugpr_valid => '0', ugpr => (others => '0'));
|
||||||
|
|
||||||
|
type pipeline_t is array(0 to PIPELINE_DEPTH) of pipeline_entry_type;
|
||||||
|
constant pipeline_t_init : pipeline_t := (others => pipeline_entry_init);
|
||||||
|
|
||||||
|
signal r, rin : pipeline_t := pipeline_t_init;
|
||||||
|
begin
|
||||||
|
gpr_hazard0: process(clk)
|
||||||
|
begin
|
||||||
|
if rising_edge(clk) then
|
||||||
|
r <= rin;
|
||||||
|
end if;
|
||||||
|
end process;
|
||||||
|
|
||||||
|
gpr_hazard1: process(all)
|
||||||
|
variable v : pipeline_t;
|
||||||
|
begin
|
||||||
|
v := r;
|
||||||
|
|
||||||
|
if complete_in = '1' then
|
||||||
|
v(PIPELINE_DEPTH).valid := '0';
|
||||||
|
v(PIPELINE_DEPTH).ugpr_valid := '0';
|
||||||
|
end if;
|
||||||
|
|
||||||
|
stall_out <= '0';
|
||||||
|
use_bypass <= '0';
|
||||||
|
if gpr_read_valid_in = '1' then
|
||||||
|
loop_0: for i in 0 to PIPELINE_DEPTH loop
|
||||||
|
if v(i).valid = '1' and r(i).gpr = gpr_read_in then
|
||||||
|
if r(i).bypass = '1' then
|
||||||
|
use_bypass <= '1';
|
||||||
|
else
|
||||||
|
stall_out <= '1';
|
||||||
|
end if;
|
||||||
|
end if;
|
||||||
|
if v(i).ugpr_valid = '1' and r(i).ugpr = gpr_read_in then
|
||||||
|
stall_out <= '1';
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- XXX assumes PIPELINE_DEPTH = 1
|
||||||
|
if busy_in = '0' then
|
||||||
|
v(1) := v(0);
|
||||||
|
v(0).valid := '0';
|
||||||
|
v(0).ugpr_valid := '0';
|
||||||
|
end if;
|
||||||
|
if deferred = '0' and issuing = '1' then
|
||||||
|
v(0).valid := gpr_write_valid_in;
|
||||||
|
v(0).bypass := bypass_avail;
|
||||||
|
v(0).gpr := gpr_write_in;
|
||||||
|
v(0).ugpr_valid := ugpr_write_valid;
|
||||||
|
v(0).ugpr := ugpr_write_reg;
|
||||||
|
end if;
|
||||||
|
if flush_in = '1' then
|
||||||
|
v(0).valid := '0';
|
||||||
|
v(0).ugpr_valid := '0';
|
||||||
|
v(1).valid := '0';
|
||||||
|
v(1).ugpr_valid := '0';
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- update registers
|
||||||
|
rin <= v;
|
||||||
|
|
||||||
|
end process;
|
||||||
|
end;
|
Binary file not shown.
Binary file not shown.
@ -1,27 +1,13 @@
|
|||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 0;
|
|
||||||
_start = .;
|
_start = .;
|
||||||
|
. = 0;
|
||||||
.head : {
|
.head : {
|
||||||
KEEP(*(.head))
|
KEEP(*(.head))
|
||||||
}
|
}
|
||||||
. = 0x1000;
|
. = 0x400;
|
||||||
.text : { *(.text) *(.text.*) *(.rodata) *(.rodata.*) }
|
.text : { *(.text) }
|
||||||
. = 0x1800;
|
. = 0xA00;
|
||||||
.data : { *(.data) *(.data.*) *(.got) *(.toc) }
|
.data : { *(.data) }
|
||||||
. = ALIGN(0x80);
|
.bss : { *(.bss) }
|
||||||
__bss_start = .;
|
|
||||||
.bss : {
|
|
||||||
*(.dynsbss)
|
|
||||||
*(.sbss)
|
|
||||||
*(.scommon)
|
|
||||||
*(.dynbss)
|
|
||||||
*(.bss)
|
|
||||||
*(.common)
|
|
||||||
*(.bss.*)
|
|
||||||
}
|
|
||||||
. = ALIGN(0x80);
|
|
||||||
__bss_end = .;
|
|
||||||
. = . + 0x2000;
|
|
||||||
__stack_top = .;
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
@ -1,39 +0,0 @@
|
|||||||
# Matt Johnston 2021
|
|
||||||
# Based on parameters from Greg Davill's Orangecrab-test-sw
|
|
||||||
|
|
||||||
{
|
|
||||||
"cpu": "None", # CPU type (ex vexriscv, serv, None)
|
|
||||||
"device": "LFE5U-85F-8MG285C",
|
|
||||||
"memtype": "DDR3", # DRAM type
|
|
||||||
|
|
||||||
"sdram_module": "MT41K256M16", # SDRAM modules of the board or SO-DIMM
|
|
||||||
"sdram_module_nb": 2, # Number of byte groups
|
|
||||||
"sdram_rank_nb": 1, # Number of ranks
|
|
||||||
"sdram_phy": "ECP5DDRPHY", # Type of FPGA PHY
|
|
||||||
|
|
||||||
# Electrical ---------------------------------------------------------------
|
|
||||||
"rtt_nom": "disabled", # Nominal termination. ("disabled" from orangecrab)
|
|
||||||
"rtt_wr": "60ohm", # Write termination. (Default)
|
|
||||||
"ron": "34ohm", # Output driver impedance. (Default)
|
|
||||||
|
|
||||||
# Frequency ----------------------------------------------------------------
|
|
||||||
"init_clk_freq": 24e6,
|
|
||||||
"input_clk_freq": 48e6, # Input clock frequency
|
|
||||||
"sys_clk_freq": 48e6, # System clock frequency (DDR_clk = 4 x sys_clk)
|
|
||||||
|
|
||||||
# 0 if freq >64e6 else 100. https://github.com/enjoy-digital/litedram/issues/130
|
|
||||||
"cmd_delay": 100,
|
|
||||||
|
|
||||||
# Core ---------------------------------------------------------------------
|
|
||||||
"cmd_buffer_depth": 16, # Depth of the command buffer
|
|
||||||
|
|
||||||
"dm_swap": true,
|
|
||||||
|
|
||||||
# User Ports ---------------------------------------------------------------
|
|
||||||
"user_ports": {
|
|
||||||
"native_0": {
|
|
||||||
"type": "native",
|
|
||||||
"block_until_ready": False,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
# This file is Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
|
||||||
# License: BSD
|
|
||||||
|
|
||||||
{
|
|
||||||
# General ------------------------------------------------------------------
|
|
||||||
"cpu": "None", # CPU type (ex vexriscv, serv, None)
|
|
||||||
"speedgrade": -1, # FPGA speedgrade
|
|
||||||
"memtype": "DDR3", # DRAM type
|
|
||||||
|
|
||||||
# PHY ----------------------------------------------------------------------
|
|
||||||
"cmd_latency": 0, # Command additional latency
|
|
||||||
"sdram_module": "MT41K128M16", # SDRAM modules of the board or SO-DIMM
|
|
||||||
"sdram_module_nb": 2, # Number of byte groups
|
|
||||||
"sdram_rank_nb": 1, # Number of ranks
|
|
||||||
"sdram_phy": "A7DDRPHY", # Type of FPGA PHY
|
|
||||||
|
|
||||||
# Electrical ---------------------------------------------------------------
|
|
||||||
"rtt_nom": "60ohm", # Nominal termination
|
|
||||||
"rtt_wr": "60ohm", # Write termination
|
|
||||||
"ron": "34ohm", # Output driver impedance
|
|
||||||
|
|
||||||
# Frequency ----------------------------------------------------------------
|
|
||||||
"input_clk_freq": 50e6, # Input clock frequency
|
|
||||||
"sys_clk_freq": 100e6, # System clock frequency (DDR_clk = 4 x sys_clk)
|
|
||||||
"iodelay_clk_freq": 200e6, # IODELAYs reference clock frequency
|
|
||||||
|
|
||||||
# Core ---------------------------------------------------------------------
|
|
||||||
"cmd_buffer_depth": 16, # Depth of the command buffer
|
|
||||||
|
|
||||||
# User Ports ---------------------------------------------------------------
|
|
||||||
"user_ports": {
|
|
||||||
"native_0": {
|
|
||||||
"type": "native",
|
|
||||||
"block_until_ready": False,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@ -1,123 +0,0 @@
|
|||||||
library ieee;
|
|
||||||
use ieee.std_logic_1164.all;
|
|
||||||
use ieee.numeric_std.all;
|
|
||||||
use std.textio.all;
|
|
||||||
|
|
||||||
library work;
|
|
||||||
use work.wishbone_types.all;
|
|
||||||
use work.utils.all;
|
|
||||||
|
|
||||||
entity dram_init_mem is
|
|
||||||
generic (
|
|
||||||
EXTRA_PAYLOAD_FILE : string := "";
|
|
||||||
EXTRA_PAYLOAD_SIZE : integer := 0
|
|
||||||
);
|
|
||||||
port (
|
|
||||||
clk : in std_ulogic;
|
|
||||||
wb_in : in wb_io_master_out;
|
|
||||||
wb_out : out wb_io_slave_out
|
|
||||||
);
|
|
||||||
end entity dram_init_mem;
|
|
||||||
|
|
||||||
architecture rtl of dram_init_mem is
|
|
||||||
|
|
||||||
constant INIT_RAM_SIZE : integer := 24576;
|
|
||||||
constant RND_PAYLOAD_SIZE : integer := round_up(EXTRA_PAYLOAD_SIZE, 8);
|
|
||||||
constant TOTAL_RAM_SIZE : integer := INIT_RAM_SIZE + RND_PAYLOAD_SIZE;
|
|
||||||
constant INIT_RAM_ABITS : integer := log2ceil(TOTAL_RAM_SIZE-1);
|
|
||||||
constant INIT_RAM_FILE : string := "litedram_core.init";
|
|
||||||
|
|
||||||
type ram_t is array(0 to (TOTAL_RAM_SIZE / 4) - 1) of std_logic_vector(31 downto 0);
|
|
||||||
|
|
||||||
-- XXX FIXME: Have a single init function called twice with
|
|
||||||
-- an offset as argument
|
|
||||||
procedure init_load_payload(ram: inout ram_t; filename: string) is
|
|
||||||
file payload_file : text open read_mode is filename;
|
|
||||||
variable ram_line : line;
|
|
||||||
variable temp_word : std_logic_vector(63 downto 0);
|
|
||||||
begin
|
|
||||||
for i in 0 to RND_PAYLOAD_SIZE-1 loop
|
|
||||||
exit when endfile(payload_file);
|
|
||||||
readline(payload_file, ram_line);
|
|
||||||
hread(ram_line, temp_word);
|
|
||||||
ram((INIT_RAM_SIZE/4) + i*2) := temp_word(31 downto 0);
|
|
||||||
ram((INIT_RAM_SIZE/4) + i*2+1) := temp_word(63 downto 32);
|
|
||||||
end loop;
|
|
||||||
assert endfile(payload_file) report "Payload too big !" severity failure;
|
|
||||||
end procedure;
|
|
||||||
|
|
||||||
impure function init_load_ram(name : string) return ram_t is
|
|
||||||
file ram_file : text open read_mode is name;
|
|
||||||
variable temp_word : std_logic_vector(63 downto 0);
|
|
||||||
variable temp_ram : ram_t := (others => (others => '0'));
|
|
||||||
variable ram_line : line;
|
|
||||||
begin
|
|
||||||
report "Payload size:" & integer'image(EXTRA_PAYLOAD_SIZE) &
|
|
||||||
" rounded to:" & integer'image(RND_PAYLOAD_SIZE);
|
|
||||||
report "Total RAM size:" & integer'image(TOTAL_RAM_SIZE) &
|
|
||||||
" bytes using " & integer'image(INIT_RAM_ABITS) &
|
|
||||||
" address bits";
|
|
||||||
for i in 0 to (INIT_RAM_SIZE/8)-1 loop
|
|
||||||
exit when endfile(ram_file);
|
|
||||||
readline(ram_file, ram_line);
|
|
||||||
hread(ram_line, temp_word);
|
|
||||||
temp_ram(i*2) := temp_word(31 downto 0);
|
|
||||||
temp_ram(i*2+1) := temp_word(63 downto 32);
|
|
||||||
end loop;
|
|
||||||
if RND_PAYLOAD_SIZE /= 0 then
|
|
||||||
init_load_payload(temp_ram, EXTRA_PAYLOAD_FILE);
|
|
||||||
end if;
|
|
||||||
return temp_ram;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
impure function init_zero return ram_t is
|
|
||||||
variable temp_ram : ram_t := (others => (others => '0'));
|
|
||||||
begin
|
|
||||||
return temp_ram;
|
|
||||||
end function;
|
|
||||||
|
|
||||||
impure function initialize_ram(filename: string) return ram_t is
|
|
||||||
begin
|
|
||||||
report "Opening file " & filename;
|
|
||||||
if filename'length = 0 then
|
|
||||||
return init_zero;
|
|
||||||
else
|
|
||||||
return init_load_ram(filename);
|
|
||||||
end if;
|
|
||||||
end function;
|
|
||||||
signal init_ram : ram_t := initialize_ram(INIT_RAM_FILE);
|
|
||||||
|
|
||||||
attribute ram_style : string;
|
|
||||||
attribute ram_style of init_ram: signal is "block";
|
|
||||||
|
|
||||||
signal obuf : std_ulogic_vector(31 downto 0);
|
|
||||||
signal oack : std_ulogic;
|
|
||||||
begin
|
|
||||||
|
|
||||||
init_ram_0: process(clk)
|
|
||||||
variable adr : integer;
|
|
||||||
begin
|
|
||||||
if rising_edge(clk) then
|
|
||||||
oack <= '0';
|
|
||||||
if (wb_in.cyc and wb_in.stb) = '1' then
|
|
||||||
adr := to_integer((unsigned(wb_in.adr(INIT_RAM_ABITS - 3 downto 0))));
|
|
||||||
if wb_in.we = '0' then
|
|
||||||
obuf <= init_ram(adr);
|
|
||||||
else
|
|
||||||
for i in 0 to 3 loop
|
|
||||||
if wb_in.sel(i) = '1' then
|
|
||||||
init_ram(adr)(((i + 1) * 8) - 1 downto i * 8) <=
|
|
||||||
wb_in.dat(((i + 1) * 8) - 1 downto i * 8);
|
|
||||||
end if;
|
|
||||||
end loop;
|
|
||||||
end if;
|
|
||||||
oack <= '1';
|
|
||||||
end if;
|
|
||||||
wb_out.ack <= oack;
|
|
||||||
wb_out.dat <= obuf;
|
|
||||||
end if;
|
|
||||||
end process;
|
|
||||||
|
|
||||||
wb_out.stall <= '0';
|
|
||||||
|
|
||||||
end architecture rtl;
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue