Clone vivado dir into quartus dir
This commit is contained in:
parent
9d13c05dd2
commit
7bf87502aa
|
@ -0,0 +1,18 @@
|
||||||
|
.Xil/
|
||||||
|
firmware.bin
|
||||||
|
firmware.elf
|
||||||
|
firmware.hex
|
||||||
|
firmware.map
|
||||||
|
synth_*.log
|
||||||
|
synth_*.mmi
|
||||||
|
synth_*.bit
|
||||||
|
synth_system.v
|
||||||
|
table.txt
|
||||||
|
tab_*/
|
||||||
|
webtalk.jou
|
||||||
|
webtalk.log
|
||||||
|
webtalk_*.jou
|
||||||
|
webtalk_*.log
|
||||||
|
xelab.*
|
||||||
|
xsim.*
|
||||||
|
xvlog.*
|
|
@ -0,0 +1,65 @@
|
||||||
|
|
||||||
|
VIVADO_BASE = /opt/Xilinx/Vivado/2016.1
|
||||||
|
VIVADO = $(VIVADO_BASE)/bin/vivado
|
||||||
|
XVLOG = $(VIVADO_BASE)/bin/xvlog
|
||||||
|
XELAB = $(VIVADO_BASE)/bin/xelab
|
||||||
|
GLBL = $(VIVADO_BASE)/data/verilog/src/glbl.v
|
||||||
|
TOOLCHAIN_PREFIX = riscv64-unknown-elf-
|
||||||
|
|
||||||
|
export VIVADO
|
||||||
|
|
||||||
|
help:
|
||||||
|
@echo ""
|
||||||
|
@echo "Simple synthesis tests:"
|
||||||
|
@echo " make synth_area_{small|regular|large}"
|
||||||
|
@echo " make synth_speed"
|
||||||
|
@echo ""
|
||||||
|
@echo "Example system:"
|
||||||
|
@echo " make synth_system"
|
||||||
|
@echo " make sim_system"
|
||||||
|
@echo ""
|
||||||
|
@echo "Timing and Utilization Evaluation:"
|
||||||
|
@echo " make table.txt"
|
||||||
|
@echo " make area"
|
||||||
|
@echo ""
|
||||||
|
|
||||||
|
synth_%:
|
||||||
|
rm -f $@.log
|
||||||
|
$(VIVADO) -nojournal -log $@.log -mode batch -source $@.tcl
|
||||||
|
rm -rf .Xil fsm_encoding.os synth_*.backup.log usage_statistics_webtalk.*
|
||||||
|
-grep -B4 -A10 'Slice LUTs' $@.log
|
||||||
|
-grep -B1 -A9 ^Slack $@.log && echo
|
||||||
|
|
||||||
|
synth_system: firmware.hex
|
||||||
|
|
||||||
|
sim_system:
|
||||||
|
$(XVLOG) system_tb.v synth_system.v
|
||||||
|
$(XVLOG) $(GLBL)
|
||||||
|
$(XELAB) -L unifast_ver -L unisims_ver -R system_tb glbl
|
||||||
|
|
||||||
|
firmware.hex: firmware.S firmware.c firmware.lds
|
||||||
|
$(TOOLCHAIN_PREFIX)gcc -Os -m32 -ffreestanding -nostdlib -o firmware.elf firmware.S firmware.c \
|
||||||
|
--std=gnu99 -Wl,-Bstatic,-T,firmware.lds,-Map,firmware.map,--strip-debug -lgcc
|
||||||
|
$(TOOLCHAIN_PREFIX)objcopy -O binary firmware.elf firmware.bin
|
||||||
|
python3 ../../firmware/makehex.py firmware.bin 4096 > firmware.hex
|
||||||
|
|
||||||
|
tab_%/results.txt:
|
||||||
|
bash tabtest.sh $@
|
||||||
|
|
||||||
|
area: synth_area_small synth_area_regular synth_area_large
|
||||||
|
-grep -B4 -A10 'Slice LUTs' synth_area_small.log synth_area_regular.log synth_area_large.log
|
||||||
|
|
||||||
|
table.txt: tab_small_xc7a_1/results.txt tab_small_xc7a_2/results.txt tab_small_xc7a_3/results.txt
|
||||||
|
table.txt: tab_small_xc7k_1/results.txt tab_small_xc7k_2/results.txt tab_small_xc7k_3/results.txt
|
||||||
|
table.txt: tab_small_xc7v_1/results.txt tab_small_xc7v_2/results.txt tab_small_xc7v_3/results.txt
|
||||||
|
table.txt: tab_small_xcku_1/results.txt tab_small_xcku_2/results.txt tab_small_xcku_3/results.txt
|
||||||
|
table.txt: tab_small_xcvu_1/results.txt tab_small_xcvu_2/results.txt tab_small_xcvu_3/results.txt
|
||||||
|
|
||||||
|
table.txt:
|
||||||
|
bash table.sh > table.txt
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf .Xil/ firmware.bin firmware.elf firmware.hex firmware.map synth_*.log
|
||||||
|
rm -rf synth_*.mmi synth_*.bit synth_system.v table.txt tab_*/ webtalk.jou
|
||||||
|
rm -rf webtalk.log webtalk_*.jou webtalk_*.log xelab.* xsim[._]* xvlog.*
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
.section .init
|
||||||
|
.global main
|
||||||
|
|
||||||
|
/* set stack pointer */
|
||||||
|
lui sp, %hi(16*1024)
|
||||||
|
addi sp, sp, %lo(16*1024)
|
||||||
|
|
||||||
|
/* call main */
|
||||||
|
jal ra, main
|
||||||
|
|
||||||
|
/* break */
|
||||||
|
ebreak
|
|
@ -0,0 +1,43 @@
|
||||||
|
void putc(char c)
|
||||||
|
{
|
||||||
|
*(volatile char*)0x10000000 = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void puts(const char *s)
|
||||||
|
{
|
||||||
|
while (*s) putc(*s++);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *memcpy(void *dest, const void *src, int n)
|
||||||
|
{
|
||||||
|
while (n) {
|
||||||
|
n--;
|
||||||
|
((char*)dest)[n] = ((char*)src)[n];
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
char message[] = "$Uryyb+Jbeyq!+Vs+lbh+pna+ernq+guvf+zrffntr+gura$gur+CvpbEI32+PCH"
|
||||||
|
"+frrzf+gb+or+jbexvat+whfg+svar.$$++++++++++++++++GRFG+CNFFRQ!$$";
|
||||||
|
for (int i = 0; message[i]; i++)
|
||||||
|
switch (message[i])
|
||||||
|
{
|
||||||
|
case 'a' ... 'm':
|
||||||
|
case 'A' ... 'M':
|
||||||
|
message[i] += 13;
|
||||||
|
break;
|
||||||
|
case 'n' ... 'z':
|
||||||
|
case 'N' ... 'Z':
|
||||||
|
message[i] -= 13;
|
||||||
|
break;
|
||||||
|
case '$':
|
||||||
|
message[i] = '\n';
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
message[i] = ' ';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
puts(message);
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
SECTIONS {
|
||||||
|
.memory : {
|
||||||
|
. = 0x000000;
|
||||||
|
*(.init);
|
||||||
|
*(.text);
|
||||||
|
*(*);
|
||||||
|
. = ALIGN(4);
|
||||||
|
end = .;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
read_verilog ../../picorv32.v
|
||||||
|
read_xdc synth_area.xdc
|
||||||
|
|
||||||
|
synth_design -part xc7k70t-fbg676 -top picorv32_axi
|
||||||
|
opt_design -resynth_seq_area
|
||||||
|
|
||||||
|
report_utilization
|
||||||
|
report_timing
|
|
@ -0,0 +1 @@
|
||||||
|
create_clock -period 20.00 [get_ports clk]
|
|
@ -0,0 +1,10 @@
|
||||||
|
read_verilog ../../picorv32.v
|
||||||
|
read_verilog synth_area_top.v
|
||||||
|
read_xdc synth_area.xdc
|
||||||
|
|
||||||
|
synth_design -part xc7k70t-fbg676 -top top_large
|
||||||
|
opt_design -sweep -propconst -resynth_seq_area
|
||||||
|
opt_design -directive ExploreSequentialArea
|
||||||
|
|
||||||
|
report_utilization
|
||||||
|
report_timing
|
|
@ -0,0 +1,10 @@
|
||||||
|
read_verilog ../../picorv32.v
|
||||||
|
read_verilog synth_area_top.v
|
||||||
|
read_xdc synth_area.xdc
|
||||||
|
|
||||||
|
synth_design -part xc7k70t-fbg676 -top top_regular
|
||||||
|
opt_design -sweep -propconst -resynth_seq_area
|
||||||
|
opt_design -directive ExploreSequentialArea
|
||||||
|
|
||||||
|
report_utilization
|
||||||
|
report_timing
|
|
@ -0,0 +1,10 @@
|
||||||
|
read_verilog ../../picorv32.v
|
||||||
|
read_verilog synth_area_top.v
|
||||||
|
read_xdc synth_area.xdc
|
||||||
|
|
||||||
|
synth_design -part xc7k70t-fbg676 -top top_small
|
||||||
|
opt_design -sweep -propconst -resynth_seq_area
|
||||||
|
opt_design -directive ExploreSequentialArea
|
||||||
|
|
||||||
|
report_utilization
|
||||||
|
report_timing
|
|
@ -0,0 +1,140 @@
|
||||||
|
|
||||||
|
module top_small (
|
||||||
|
input clk, resetn,
|
||||||
|
|
||||||
|
output mem_valid,
|
||||||
|
output mem_instr,
|
||||||
|
input mem_ready,
|
||||||
|
|
||||||
|
output [31:0] mem_addr,
|
||||||
|
output [31:0] mem_wdata,
|
||||||
|
output [ 3:0] mem_wstrb,
|
||||||
|
input [31:0] mem_rdata
|
||||||
|
);
|
||||||
|
picorv32 #(
|
||||||
|
.ENABLE_COUNTERS(0),
|
||||||
|
.LATCHED_MEM_RDATA(1),
|
||||||
|
.TWO_STAGE_SHIFT(0),
|
||||||
|
.CATCH_MISALIGN(0),
|
||||||
|
.CATCH_ILLINSN(0)
|
||||||
|
) picorv32 (
|
||||||
|
.clk (clk ),
|
||||||
|
.resetn (resetn ),
|
||||||
|
.mem_valid(mem_valid),
|
||||||
|
.mem_instr(mem_instr),
|
||||||
|
.mem_ready(mem_ready),
|
||||||
|
.mem_addr (mem_addr ),
|
||||||
|
.mem_wdata(mem_wdata),
|
||||||
|
.mem_wstrb(mem_wstrb),
|
||||||
|
.mem_rdata(mem_rdata)
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module top_regular (
|
||||||
|
input clk, resetn,
|
||||||
|
output trap,
|
||||||
|
|
||||||
|
output mem_valid,
|
||||||
|
output mem_instr,
|
||||||
|
input mem_ready,
|
||||||
|
|
||||||
|
output [31:0] mem_addr,
|
||||||
|
output [31:0] mem_wdata,
|
||||||
|
output [ 3:0] mem_wstrb,
|
||||||
|
input [31:0] mem_rdata,
|
||||||
|
|
||||||
|
// Look-Ahead Interface
|
||||||
|
output mem_la_read,
|
||||||
|
output mem_la_write,
|
||||||
|
output [31:0] mem_la_addr,
|
||||||
|
output [31:0] mem_la_wdata,
|
||||||
|
output [ 3:0] mem_la_wstrb
|
||||||
|
);
|
||||||
|
picorv32 picorv32 (
|
||||||
|
.clk (clk ),
|
||||||
|
.resetn (resetn ),
|
||||||
|
.trap (trap ),
|
||||||
|
.mem_valid (mem_valid ),
|
||||||
|
.mem_instr (mem_instr ),
|
||||||
|
.mem_ready (mem_ready ),
|
||||||
|
.mem_addr (mem_addr ),
|
||||||
|
.mem_wdata (mem_wdata ),
|
||||||
|
.mem_wstrb (mem_wstrb ),
|
||||||
|
.mem_rdata (mem_rdata ),
|
||||||
|
.mem_la_read (mem_la_read ),
|
||||||
|
.mem_la_write(mem_la_write),
|
||||||
|
.mem_la_addr (mem_la_addr ),
|
||||||
|
.mem_la_wdata(mem_la_wdata),
|
||||||
|
.mem_la_wstrb(mem_la_wstrb)
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module top_large (
|
||||||
|
input clk, resetn,
|
||||||
|
output trap,
|
||||||
|
|
||||||
|
output mem_valid,
|
||||||
|
output mem_instr,
|
||||||
|
input mem_ready,
|
||||||
|
|
||||||
|
output [31:0] mem_addr,
|
||||||
|
output [31:0] mem_wdata,
|
||||||
|
output [ 3:0] mem_wstrb,
|
||||||
|
input [31:0] mem_rdata,
|
||||||
|
|
||||||
|
// Look-Ahead Interface
|
||||||
|
output mem_la_read,
|
||||||
|
output mem_la_write,
|
||||||
|
output [31:0] mem_la_addr,
|
||||||
|
output [31:0] mem_la_wdata,
|
||||||
|
output [ 3:0] mem_la_wstrb,
|
||||||
|
|
||||||
|
// Pico Co-Processor Interface (PCPI)
|
||||||
|
output pcpi_valid,
|
||||||
|
output [31:0] pcpi_insn,
|
||||||
|
output [31:0] pcpi_rs1,
|
||||||
|
output [31:0] pcpi_rs2,
|
||||||
|
input pcpi_wr,
|
||||||
|
input [31:0] pcpi_rd,
|
||||||
|
input pcpi_wait,
|
||||||
|
input pcpi_ready,
|
||||||
|
|
||||||
|
// IRQ Interface
|
||||||
|
input [31:0] irq,
|
||||||
|
output [31:0] eoi
|
||||||
|
);
|
||||||
|
picorv32 #(
|
||||||
|
.COMPRESSED_ISA(1),
|
||||||
|
.BARREL_SHIFTER(1),
|
||||||
|
.ENABLE_PCPI(1),
|
||||||
|
.ENABLE_MUL(1),
|
||||||
|
.ENABLE_IRQ(1)
|
||||||
|
) picorv32 (
|
||||||
|
.clk (clk ),
|
||||||
|
.resetn (resetn ),
|
||||||
|
.trap (trap ),
|
||||||
|
.mem_valid (mem_valid ),
|
||||||
|
.mem_instr (mem_instr ),
|
||||||
|
.mem_ready (mem_ready ),
|
||||||
|
.mem_addr (mem_addr ),
|
||||||
|
.mem_wdata (mem_wdata ),
|
||||||
|
.mem_wstrb (mem_wstrb ),
|
||||||
|
.mem_rdata (mem_rdata ),
|
||||||
|
.mem_la_read (mem_la_read ),
|
||||||
|
.mem_la_write (mem_la_write ),
|
||||||
|
.mem_la_addr (mem_la_addr ),
|
||||||
|
.mem_la_wdata (mem_la_wdata ),
|
||||||
|
.mem_la_wstrb (mem_la_wstrb ),
|
||||||
|
.pcpi_valid (pcpi_valid ),
|
||||||
|
.pcpi_insn (pcpi_insn ),
|
||||||
|
.pcpi_rs1 (pcpi_rs1 ),
|
||||||
|
.pcpi_rs2 (pcpi_rs2 ),
|
||||||
|
.pcpi_wr (pcpi_wr ),
|
||||||
|
.pcpi_rd (pcpi_rd ),
|
||||||
|
.pcpi_wait (pcpi_wait ),
|
||||||
|
.pcpi_ready (pcpi_ready ),
|
||||||
|
.irq (irq ),
|
||||||
|
.eoi (eoi )
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
read_verilog ../../picorv32.v
|
||||||
|
read_xdc synth_speed.xdc
|
||||||
|
|
||||||
|
synth_design -part xc7k70t-fbg676 -top picorv32_axi
|
||||||
|
opt_design
|
||||||
|
place_design
|
||||||
|
phys_opt_design
|
||||||
|
route_design
|
||||||
|
|
||||||
|
report_utilization
|
||||||
|
report_timing
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
create_clock -period 2.50 [get_ports clk]
|
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
read_verilog system.v
|
||||||
|
read_verilog ../../picorv32.v
|
||||||
|
read_xdc synth_system.xdc
|
||||||
|
|
||||||
|
synth_design -part xc7a35t-cpg236-1 -top system
|
||||||
|
opt_design
|
||||||
|
place_design
|
||||||
|
route_design
|
||||||
|
|
||||||
|
report_utilization
|
||||||
|
report_timing
|
||||||
|
|
||||||
|
write_verilog -force synth_system.v
|
||||||
|
write_bitstream -force synth_system.bit
|
||||||
|
# write_mem_info -force synth_system.mmi
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
|
||||||
|
# XDC File for Basys3 Board
|
||||||
|
###########################
|
||||||
|
|
||||||
|
set_property PACKAGE_PIN W5 [get_ports clk]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports clk]
|
||||||
|
create_clock -period 10.00 [get_ports clk]
|
||||||
|
|
||||||
|
# Pmod Header JA (JA0..JA7)
|
||||||
|
set_property PACKAGE_PIN J1 [get_ports {out_byte[0]}]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports {out_byte[0]}]
|
||||||
|
set_property PACKAGE_PIN L2 [get_ports {out_byte[1]}]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports {out_byte[1]}]
|
||||||
|
set_property PACKAGE_PIN J2 [get_ports {out_byte[2]}]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports {out_byte[2]}]
|
||||||
|
set_property PACKAGE_PIN G2 [get_ports {out_byte[3]}]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports {out_byte[3]}]
|
||||||
|
set_property PACKAGE_PIN H1 [get_ports {out_byte[4]}]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports {out_byte[4]}]
|
||||||
|
set_property PACKAGE_PIN K2 [get_ports {out_byte[5]}]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports {out_byte[5]}]
|
||||||
|
set_property PACKAGE_PIN H2 [get_ports {out_byte[6]}]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports {out_byte[6]}]
|
||||||
|
set_property PACKAGE_PIN G3 [get_ports {out_byte[7]}]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports {out_byte[7]}]
|
||||||
|
|
||||||
|
# Pmod Header JB (JB0..JB2)
|
||||||
|
set_property PACKAGE_PIN A14 [get_ports {resetn}]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports {resetn}]
|
||||||
|
set_property PACKAGE_PIN A16 [get_ports {trap}]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports {trap}]
|
||||||
|
set_property PACKAGE_PIN B15 [get_ports {out_byte_en}]
|
||||||
|
set_property IOSTANDARD LVCMOS33 [get_ports {out_byte_en}]
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
`timescale 1 ns / 1 ps
|
||||||
|
|
||||||
|
module system (
|
||||||
|
input clk,
|
||||||
|
input resetn,
|
||||||
|
output trap,
|
||||||
|
output reg [7:0] out_byte,
|
||||||
|
output reg out_byte_en
|
||||||
|
);
|
||||||
|
// set this to 0 for better timing but less performance/MHz
|
||||||
|
parameter FAST_MEMORY = 1;
|
||||||
|
|
||||||
|
// 4096 32bit words = 16kB memory
|
||||||
|
parameter MEM_SIZE = 4096;
|
||||||
|
|
||||||
|
wire mem_valid;
|
||||||
|
wire mem_instr;
|
||||||
|
reg mem_ready;
|
||||||
|
wire [31:0] mem_addr;
|
||||||
|
wire [31:0] mem_wdata;
|
||||||
|
wire [3:0] mem_wstrb;
|
||||||
|
reg [31:0] mem_rdata;
|
||||||
|
|
||||||
|
wire mem_la_read;
|
||||||
|
wire mem_la_write;
|
||||||
|
wire [31:0] mem_la_addr;
|
||||||
|
wire [31:0] mem_la_wdata;
|
||||||
|
wire [3:0] mem_la_wstrb;
|
||||||
|
|
||||||
|
picorv32 picorv32_core (
|
||||||
|
.clk (clk ),
|
||||||
|
.resetn (resetn ),
|
||||||
|
.trap (trap ),
|
||||||
|
.mem_valid (mem_valid ),
|
||||||
|
.mem_instr (mem_instr ),
|
||||||
|
.mem_ready (mem_ready ),
|
||||||
|
.mem_addr (mem_addr ),
|
||||||
|
.mem_wdata (mem_wdata ),
|
||||||
|
.mem_wstrb (mem_wstrb ),
|
||||||
|
.mem_rdata (mem_rdata ),
|
||||||
|
.mem_la_read (mem_la_read ),
|
||||||
|
.mem_la_write(mem_la_write),
|
||||||
|
.mem_la_addr (mem_la_addr ),
|
||||||
|
.mem_la_wdata(mem_la_wdata),
|
||||||
|
.mem_la_wstrb(mem_la_wstrb)
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [31:0] memory [0:MEM_SIZE-1];
|
||||||
|
initial $readmemh("firmware.hex", memory);
|
||||||
|
|
||||||
|
reg [31:0] m_read_data;
|
||||||
|
reg m_read_en;
|
||||||
|
|
||||||
|
generate if (FAST_MEMORY) begin
|
||||||
|
always @(posedge clk) begin
|
||||||
|
mem_ready <= 1;
|
||||||
|
out_byte_en <= 0;
|
||||||
|
mem_rdata <= memory[mem_la_addr >> 2];
|
||||||
|
if (mem_la_write && (mem_la_addr >> 2) < MEM_SIZE) begin
|
||||||
|
if (mem_la_wstrb[0]) memory[mem_la_addr >> 2][ 7: 0] <= mem_la_wdata[ 7: 0];
|
||||||
|
if (mem_la_wstrb[1]) memory[mem_la_addr >> 2][15: 8] <= mem_la_wdata[15: 8];
|
||||||
|
if (mem_la_wstrb[2]) memory[mem_la_addr >> 2][23:16] <= mem_la_wdata[23:16];
|
||||||
|
if (mem_la_wstrb[3]) memory[mem_la_addr >> 2][31:24] <= mem_la_wdata[31:24];
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if (mem_la_write && mem_la_addr == 32'h1000_0000) begin
|
||||||
|
out_byte_en <= 1;
|
||||||
|
out_byte <= mem_la_wdata;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end else begin
|
||||||
|
always @(posedge clk) begin
|
||||||
|
m_read_en <= 0;
|
||||||
|
mem_ready <= mem_valid && !mem_ready && m_read_en;
|
||||||
|
|
||||||
|
m_read_data <= memory[mem_addr >> 2];
|
||||||
|
mem_rdata <= m_read_data;
|
||||||
|
|
||||||
|
out_byte_en <= 0;
|
||||||
|
|
||||||
|
(* parallel_case *)
|
||||||
|
case (1)
|
||||||
|
mem_valid && !mem_ready && !mem_wstrb && (mem_addr >> 2) < MEM_SIZE: begin
|
||||||
|
m_read_en <= 1;
|
||||||
|
end
|
||||||
|
mem_valid && !mem_ready && |mem_wstrb && (mem_addr >> 2) < MEM_SIZE: begin
|
||||||
|
if (mem_wstrb[0]) memory[mem_addr >> 2][ 7: 0] <= mem_wdata[ 7: 0];
|
||||||
|
if (mem_wstrb[1]) memory[mem_addr >> 2][15: 8] <= mem_wdata[15: 8];
|
||||||
|
if (mem_wstrb[2]) memory[mem_addr >> 2][23:16] <= mem_wdata[23:16];
|
||||||
|
if (mem_wstrb[3]) memory[mem_addr >> 2][31:24] <= mem_wdata[31:24];
|
||||||
|
mem_ready <= 1;
|
||||||
|
end
|
||||||
|
mem_valid && !mem_ready && |mem_wstrb && mem_addr == 32'h1000_0000: begin
|
||||||
|
out_byte_en <= 1;
|
||||||
|
out_byte <= mem_wdata;
|
||||||
|
mem_ready <= 1;
|
||||||
|
end
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
end endgenerate
|
||||||
|
endmodule
|
|
@ -0,0 +1,38 @@
|
||||||
|
`timescale 1 ns / 1 ps
|
||||||
|
|
||||||
|
module system_tb;
|
||||||
|
reg clk = 1;
|
||||||
|
always #5 clk = ~clk;
|
||||||
|
|
||||||
|
reg resetn = 0;
|
||||||
|
initial begin
|
||||||
|
if ($test$plusargs("vcd")) begin
|
||||||
|
$dumpfile("system.vcd");
|
||||||
|
$dumpvars(0, system_tb);
|
||||||
|
end
|
||||||
|
repeat (100) @(posedge clk);
|
||||||
|
resetn <= 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
wire trap;
|
||||||
|
wire [7:0] out_byte;
|
||||||
|
wire out_byte_en;
|
||||||
|
|
||||||
|
system uut (
|
||||||
|
.clk (clk ),
|
||||||
|
.resetn (resetn ),
|
||||||
|
.trap (trap ),
|
||||||
|
.out_byte (out_byte ),
|
||||||
|
.out_byte_en(out_byte_en)
|
||||||
|
);
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (resetn && out_byte_en) begin
|
||||||
|
$write("%c", out_byte);
|
||||||
|
$fflush;
|
||||||
|
end
|
||||||
|
if (resetn && trap) begin
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
|
@ -0,0 +1,19 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
dashes="----------------------------------------------------------------"
|
||||||
|
printf '| %-25s | %-10s | %-20s |\n' "Device" "Speedgrade" "Clock Period (Freq.)"
|
||||||
|
printf '|:%.25s |:%.10s:| %.20s:|\n' $dashes $dashes $dashes
|
||||||
|
|
||||||
|
for x in $( grep -H . tab_*/results.txt )
|
||||||
|
do
|
||||||
|
read _ size device grade _ speed < <( echo "$x" | tr _/: ' ' )
|
||||||
|
case "$device" in
|
||||||
|
xc7a) d="Xilinx Artix-7T" ;;
|
||||||
|
xc7k) d="Xilinx Kintex-7T" ;;
|
||||||
|
xc7v) d="Xilinx Virtex-7T" ;;
|
||||||
|
xcku) d="Xilinx Kintex UltraScale" ;;
|
||||||
|
xcvu) d="Xilinx Virtex UltraScale" ;;
|
||||||
|
esac
|
||||||
|
speedtxt=$( printf '%s.%s ns (%d MHz)' ${speed%?} ${speed#?} $((10000 / speed)) )
|
||||||
|
printf '| %-25s | %-10s | %20s |\n' "$d" "-$grade" "$speedtxt"
|
||||||
|
done
|
|
@ -0,0 +1,92 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
read _ ip dev grade _ < <( echo $* | tr '_/' ' '; )
|
||||||
|
|
||||||
|
# rm -rf tab_${ip}_${dev}_${grade}
|
||||||
|
mkdir -p tab_${ip}_${dev}_${grade}
|
||||||
|
cd tab_${ip}_${dev}_${grade}
|
||||||
|
|
||||||
|
best_speed=99
|
||||||
|
speed=30
|
||||||
|
step=16
|
||||||
|
|
||||||
|
synth_case() {
|
||||||
|
if [ -f test_${1}.txt ]; then
|
||||||
|
echo "Reusing cached tab_${ip}_${dev}_${grade}/test_${1}."
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "${dev}" in
|
||||||
|
xc7a) xl_device="xc7a15t-fgg484-${grade}" ;;
|
||||||
|
xc7k) xl_device="xc7k70t-fbg676-${grade}" ;;
|
||||||
|
xc7v) xl_device="xc7v585t-ffg1761-${grade}" ;;
|
||||||
|
xcku) xl_device="xcku035-fbva676-${grade}" ;;
|
||||||
|
xcvu) xl_device="xcvu065-ffvc1517-${grade}" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "${dev}-${grade}" in
|
||||||
|
xcku-1) xl_device="${xl_device}-c" ;;
|
||||||
|
xcvu-1) xl_device="${xl_device}-i" ;;
|
||||||
|
xcku-?|xcvu-?) xl_device="${xl_device}-e" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
cat > test_${1}.tcl <<- EOT
|
||||||
|
read_verilog ../tabtest.v
|
||||||
|
read_verilog ../../../picorv32.v
|
||||||
|
read_xdc test_${1}.xdc
|
||||||
|
synth_design -flatten_hierarchy full -part ${xl_device} -top top
|
||||||
|
opt_design -sweep -remap -propconst
|
||||||
|
opt_design -directive Explore
|
||||||
|
place_design -directive Explore
|
||||||
|
phys_opt_design -retime -rewire -critical_pin_opt -placement_opt -critical_cell_opt
|
||||||
|
route_design -directive Explore
|
||||||
|
place_design -post_place_opt
|
||||||
|
phys_opt_design -retime
|
||||||
|
route_design -directive NoTimingRelaxation
|
||||||
|
report_utilization
|
||||||
|
report_timing
|
||||||
|
EOT
|
||||||
|
|
||||||
|
cat > test_${1}.xdc <<- EOT
|
||||||
|
create_clock -period ${speed%?}.${speed#?} [get_ports clk]
|
||||||
|
EOT
|
||||||
|
|
||||||
|
echo "Running tab_${ip}_${dev}_${grade}/test_${1}.."
|
||||||
|
if ! $VIVADO -nojournal -log test_${1}.log -mode batch -source test_${1}.tcl > /dev/null 2>&1; then
|
||||||
|
cat test_${1}.log
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
mv test_${1}.log test_${1}.txt
|
||||||
|
}
|
||||||
|
|
||||||
|
countdown=2
|
||||||
|
while [ $countdown -gt 0 ]; do
|
||||||
|
synth_case $speed
|
||||||
|
|
||||||
|
if grep -q '^Slack.*(VIOLATED)' test_${speed}.txt; then
|
||||||
|
echo " tab_${ip}_${dev}_${grade}/test_${speed} VIOLATED"
|
||||||
|
[ $speed -eq 38 ] || step=$((step / 2))
|
||||||
|
speed=$((speed + step))
|
||||||
|
elif grep -q '^Slack.*(MET)' test_${speed}.txt; then
|
||||||
|
echo " tab_${ip}_${dev}_${grade}/test_${speed} MET"
|
||||||
|
[ $speed -lt $best_speed ] && best_speed=$speed
|
||||||
|
step=$((step / 2))
|
||||||
|
speed=$((speed - step))
|
||||||
|
else
|
||||||
|
echo "ERROR: No slack line found in $PWD/test_${speed}.txt!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ $step -eq 0 ]; then
|
||||||
|
countdown=$((countdown - 1))
|
||||||
|
speed=$((best_speed - 2))
|
||||||
|
step=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "-----------------------"
|
||||||
|
echo "Best speed for tab_${ip}_${dev}_${grade}: $best_speed"
|
||||||
|
echo "-----------------------"
|
||||||
|
echo $best_speed > results.txt
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
|
||||||
|
module top (
|
||||||
|
input clk, io_resetn,
|
||||||
|
output io_trap,
|
||||||
|
|
||||||
|
output io_mem_axi_awvalid,
|
||||||
|
input io_mem_axi_awready,
|
||||||
|
output [31:0] io_mem_axi_awaddr,
|
||||||
|
output [ 2:0] io_mem_axi_awprot,
|
||||||
|
|
||||||
|
output io_mem_axi_wvalid,
|
||||||
|
input io_mem_axi_wready,
|
||||||
|
output [31:0] io_mem_axi_wdata,
|
||||||
|
output [ 3:0] io_mem_axi_wstrb,
|
||||||
|
|
||||||
|
input io_mem_axi_bvalid,
|
||||||
|
output io_mem_axi_bready,
|
||||||
|
|
||||||
|
output io_mem_axi_arvalid,
|
||||||
|
input io_mem_axi_arready,
|
||||||
|
output [31:0] io_mem_axi_araddr,
|
||||||
|
output [ 2:0] io_mem_axi_arprot,
|
||||||
|
|
||||||
|
input io_mem_axi_rvalid,
|
||||||
|
output io_mem_axi_rready,
|
||||||
|
input [31:0] io_mem_axi_rdata,
|
||||||
|
|
||||||
|
input [31:0] io_irq,
|
||||||
|
output [31:0] io_eoi
|
||||||
|
);
|
||||||
|
wire resetn;
|
||||||
|
wire trap;
|
||||||
|
wire mem_axi_awvalid;
|
||||||
|
wire mem_axi_awready;
|
||||||
|
wire [31:0] mem_axi_awaddr;
|
||||||
|
wire [2:0] mem_axi_awprot;
|
||||||
|
wire mem_axi_wvalid;
|
||||||
|
wire mem_axi_wready;
|
||||||
|
wire [31:0] mem_axi_wdata;
|
||||||
|
wire [3:0] mem_axi_wstrb;
|
||||||
|
wire mem_axi_bvalid;
|
||||||
|
wire mem_axi_bready;
|
||||||
|
wire mem_axi_arvalid;
|
||||||
|
wire mem_axi_arready;
|
||||||
|
wire [31:0] mem_axi_araddr;
|
||||||
|
wire [2:0] mem_axi_arprot;
|
||||||
|
wire mem_axi_rvalid;
|
||||||
|
wire mem_axi_rready;
|
||||||
|
wire [31:0] mem_axi_rdata;
|
||||||
|
wire [31:0] irq;
|
||||||
|
wire [31:0] eoi;
|
||||||
|
|
||||||
|
delay4 #( 1) delay_resetn (clk, io_resetn , resetn );
|
||||||
|
delay4 #( 1) delay_trap (clk, trap , io_trap );
|
||||||
|
delay4 #( 1) delay_mem_axi_awvalid (clk, mem_axi_awvalid, io_mem_axi_awvalid);
|
||||||
|
delay4 #( 1) delay_mem_axi_awready (clk, io_mem_axi_awready, mem_axi_awready);
|
||||||
|
delay4 #(32) delay_mem_axi_awaddr (clk, mem_axi_awaddr , io_mem_axi_awaddr );
|
||||||
|
delay4 #( 3) delay_mem_axi_awprot (clk, mem_axi_awprot , io_mem_axi_awprot );
|
||||||
|
delay4 #( 1) delay_mem_axi_wvalid (clk, mem_axi_wvalid , io_mem_axi_wvalid );
|
||||||
|
delay4 #( 1) delay_mem_axi_wready (clk, io_mem_axi_wready , mem_axi_wready );
|
||||||
|
delay4 #(32) delay_mem_axi_wdata (clk, mem_axi_wdata , io_mem_axi_wdata );
|
||||||
|
delay4 #( 4) delay_mem_axi_wstrb (clk, mem_axi_wstrb , io_mem_axi_wstrb );
|
||||||
|
delay4 #( 1) delay_mem_axi_bvalid (clk, io_mem_axi_bvalid , mem_axi_bvalid );
|
||||||
|
delay4 #( 1) delay_mem_axi_bready (clk, mem_axi_bready , io_mem_axi_bready );
|
||||||
|
delay4 #( 1) delay_mem_axi_arvalid (clk, mem_axi_arvalid, io_mem_axi_arvalid);
|
||||||
|
delay4 #( 1) delay_mem_axi_arready (clk, io_mem_axi_arready, mem_axi_arready);
|
||||||
|
delay4 #(32) delay_mem_axi_araddr (clk, mem_axi_araddr , io_mem_axi_araddr );
|
||||||
|
delay4 #( 3) delay_mem_axi_arprot (clk, mem_axi_arprot , io_mem_axi_arprot );
|
||||||
|
delay4 #( 1) delay_mem_axi_rvalid (clk, io_mem_axi_rvalid , mem_axi_rvalid );
|
||||||
|
delay4 #( 1) delay_mem_axi_rready (clk, mem_axi_rready , io_mem_axi_rready );
|
||||||
|
delay4 #(32) delay_mem_axi_rdata (clk, io_mem_axi_rdata , mem_axi_rdata );
|
||||||
|
delay4 #(32) delay_irq (clk, io_irq , irq );
|
||||||
|
delay4 #(32) delay_eoi (clk, eoi , io_eoi );
|
||||||
|
|
||||||
|
picorv32_axi #(
|
||||||
|
.TWO_CYCLE_ALU(1)
|
||||||
|
) cpu (
|
||||||
|
.clk (clk ),
|
||||||
|
.resetn (resetn ),
|
||||||
|
.trap (trap ),
|
||||||
|
.mem_axi_awvalid(mem_axi_awvalid),
|
||||||
|
.mem_axi_awready(mem_axi_awready),
|
||||||
|
.mem_axi_awaddr (mem_axi_awaddr ),
|
||||||
|
.mem_axi_awprot (mem_axi_awprot ),
|
||||||
|
.mem_axi_wvalid (mem_axi_wvalid ),
|
||||||
|
.mem_axi_wready (mem_axi_wready ),
|
||||||
|
.mem_axi_wdata (mem_axi_wdata ),
|
||||||
|
.mem_axi_wstrb (mem_axi_wstrb ),
|
||||||
|
.mem_axi_bvalid (mem_axi_bvalid ),
|
||||||
|
.mem_axi_bready (mem_axi_bready ),
|
||||||
|
.mem_axi_arvalid(mem_axi_arvalid),
|
||||||
|
.mem_axi_arready(mem_axi_arready),
|
||||||
|
.mem_axi_araddr (mem_axi_araddr ),
|
||||||
|
.mem_axi_arprot (mem_axi_arprot ),
|
||||||
|
.mem_axi_rvalid (mem_axi_rvalid ),
|
||||||
|
.mem_axi_rready (mem_axi_rready ),
|
||||||
|
.mem_axi_rdata (mem_axi_rdata ),
|
||||||
|
.irq (irq ),
|
||||||
|
.eoi (eoi )
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module delay4 #(
|
||||||
|
parameter WIDTH = 1
|
||||||
|
) (
|
||||||
|
input clk,
|
||||||
|
input [WIDTH-1:0] in,
|
||||||
|
output reg [WIDTH-1:0] out
|
||||||
|
);
|
||||||
|
reg [WIDTH-1:0] q1, q2, q3;
|
||||||
|
always @(posedge clk) begin
|
||||||
|
q1 <= in;
|
||||||
|
q2 <= q1;
|
||||||
|
q3 <= q2;
|
||||||
|
out <= q3;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
Loading…
Reference in New Issue