Commit 0bebda31 authored by Dimitris Lampridis's avatar Dimitris Lampridis

[hdl] Complete rewrite of the Wishbone interface

This is done in order to:

1. Fix incompatibilities with pipelined wishbone
2. Improve performance
3, Improve code readability
parent fa316ca7
......@@ -10,6 +10,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Option for active-high reset
- Micron DD3 BFM
- SystemVerilog testbench
### Changed
- Complete rewrite of the Wishbone interface to improve performance and code readability
### Removed
- Unused file `rtl/ddr3_ctrl_wb_single.vhd`
## [1.0.0] - 2016-05-19
### Added
......
......@@ -8,7 +8,7 @@
-- Dimitrios Lampridis <dimitrios.lampridis@cern.ch>
-- Company : CERN (BE-CO-HT)
-- Created : 2011-07-13
-- Last update: 2018-11-12
-- Last update: 2020-07-07
-- Standard : VHDL'93/02
-------------------------------------------------------------------------------
-- Description: Wishbone to DDR3 interface for Xilinx FPGA with MCB (Memory
......@@ -369,6 +369,7 @@ begin
ddr_rd_count_i => p0_rd_count,
ddr_rd_overflow_i => p0_rd_overflow,
ddr_rd_error_i => p0_rd_error,
wb_rst_n_i => wb0_rst_n_i,
wb_clk_i => wb0_clk_i,
wb_sel_i => wb0_sel_i,
wb_cyc_i => wb0_cyc_i,
......@@ -417,6 +418,7 @@ begin
ddr_rd_count_i => p1_rd_count,
ddr_rd_overflow_i => p1_rd_overflow,
ddr_rd_error_i => p1_rd_error,
wb_rst_n_i => wb1_rst_n_i,
wb_clk_i => wb1_clk_i,
wb_sel_i => wb1_sel_i,
wb_cyc_i => wb1_cyc_i,
......
This diff is collapsed.
This diff is collapsed.
......@@ -126,14 +126,68 @@ module main;
wb_cycle_t c,r;
wb_xfer_t x;
const int c_NPACKETS = 200000;
const int c_ADDR_BASE = 0;
const int c_DATA_BASE = 0;
const int c_NPACKETS = 2000;
const int c_DDR_BURST = 16;
const int c_ADDR_BASE = 'h0000;
const int c_DATA_BASE = 1;
task rw_test;
input int word_count;
begin
int i;
time wr_t, rd_t;
$display("- Begin write test (%0d bytes)", word_count * 4);
c.ctype = PIPELINED;
c.rw = 1;
c.data.delete();
for (i = 0; i < word_count; i++) begin
x.a = c_ADDR_BASE + 4*i;
x.d = c_DATA_BASE + i;
x.size = 4;
c.data.push_back(x);
end
wr_t = $time;
acc.put(c);
acc.get(r);
wr_t = $time - wr_t;
$display(" %0d bytes written to DDR in %0t (%0.2f MB/s)",
word_count * 4, wr_t, 1e3 * word_count * 4.0 / wr_t);
wait (DUT.p0_wr_empty == 1);
// Perform read test of 8x full bursts
$display("- Begin read test (%0d bytes)", word_count * 4);
c.ctype = PIPELINED;
c.rw = 0;
c.data.delete();
for (i = 0; i < word_count; i++) begin
x.a = c_ADDR_BASE + 4*i;
x.size = 4;
c.data.push_back(x);
end
rd_t = $time;
acc.put(c);
acc.get(r);
rd_t = $time - rd_t;
$display(" %0d bytes read back from DDR in %0t (%0.2f MB/s)",
word_count * 4, rd_t, 1e3 * word_count * 4.0 / rd_t);
$display("- Data verification");
for (i = 0; i < word_count; i++) begin
if (r.data[i].d != c_DATA_BASE + i)
$fatal(1, "Read-back error at address %8x. Expected %8x, but got %8x instead",
r.data[i].a, c_DATA_BASE + i, r.data[i].d);
end
$display(" done");
end
endtask // rw_test
initial begin
int i;
time wr_t, rd_t;
int i;
$timeformat (-6, 3, "us", 10);
......@@ -149,68 +203,35 @@ module main;
acc = I_wb.get_accessor();
// Prime the DDR by writing a couple of dummy bursts
c.ctype = PIPELINED;
c.rw = 1;
c.data.delete();
for (i = 0; i < 100; i++) begin
x.a = c_ADDR_BASE + 4*i;
x.d = c_DATA_BASE + i;
x.size = 4;
c.data.push_back(x);
end
wait (DUT.p0_wr_full == 0);
acc.put(c);
acc.get(r);
#10us;
// Perform write test
$display("- Begin write test (%0d bytes)", c_NPACKETS * 4);
c.ctype = PIPELINED;
c.rw = 1;
c.data.delete();
for (i = 0; i < c_NPACKETS; i++) begin
x.a = c_ADDR_BASE + 4*i;
x.d = c_DATA_BASE + i;
x.size = 4;
c.data.push_back(x);
end
wr_t = $time;
acc.put(c);
acc.get(r);
wr_t = $time - wr_t;
$display(" %0d bytes written to DDR in %0t (%0.2f MB/s)",
c_NPACKETS * 4, wr_t, 1e3 * c_NPACKETS * 4.0 / wr_t);
#10us;
// Perform read test
$display("- Begin read test (%0d bytes)", c_NPACKETS * 4);
c.ctype = PIPELINED;
c.rw = 0;
c.data.delete();
for (i = 0; i < c_NPACKETS; i++) begin
x.a = c_ADDR_BASE + 4*i;
x.size = 4;
c.data.push_back(x);
end
#1us;
rd_t = $time;
acc.put(c);
acc.get(r);
rd_t = $time - rd_t;
$display(" %0d bytes read back from DDR in %0t (%0.2f MB/s)",
c_NPACKETS * 4, rd_t, 1e3 * c_NPACKETS * 4.0 / rd_t);
$display("- Data verification");
for (i = 0; i < c_NPACKETS; i++) begin
if (r.data[i].d != c_DATA_BASE + i)
$error("Read-back error at address %8x. Expected %8x, but got %8x instead",
r.data[i].a, c_DATA_BASE + i, r.data[i].d);
end
$display(" done");
// Perform write/read-back test of 8x full bursts
rw_test(c_DDR_BURST * 8);
#5us;
// Check from 1 to c_DDR_BURST -2
for (i = 1; i < c_DDR_BURST - 1; i++)
begin
rw_test(i);
#5us;
end
// Check in multiples of c_DDR_BURST, including -1 and +1 of c_DDR_BURST
// for corner cases.
for (i= 1; i < 8; i++)
begin
rw_test(i*c_DDR_BURST - 1);
#5us;
rw_test(i*c_DDR_BURST);
#5us;
rw_test(i*c_DDR_BURST + 1);
#5us;
end
// Perform long write/read-back test
rw_test(c_NPACKETS);
#1us;
......
vsim -voptargs=+acc=lprn -quiet -t 10fs -L unisim -L secureip work.main -suppress 8822,8617,8683,8684
vsim -voptargs=+acc -quiet -t 10fs -L unisim -L secureip work.main -suppress 8822,8617,8683,8684
set StdArithNoWarnings 1
set NumericStdNoWarnings 1
......
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate /main/DUT/cmp_ddr3_ctrl_wb_0/rst_n_i
add wave -noupdate /main/DUT/cmp_ddr3_ctrl_wb_0/wb_clk_i
add wave -noupdate -expand -group Wishbone /main/DUT/cmp_ddr3_ctrl_wb_0/wb_cyc_i
add wave -noupdate -expand -group Wishbone /main/DUT/cmp_ddr3_ctrl_wb_0/wb_stb_i
add wave -noupdate -expand -group Wishbone /main/DUT/cmp_ddr3_ctrl_wb_0/wb_stb_valid
add wave -noupdate -expand -group Wishbone /main/DUT/cmp_ddr3_ctrl_wb_0/wb_addr_i
add wave -noupdate -expand -group Wishbone /main/DUT/cmp_ddr3_ctrl_wb_0/wb_sel_i
add wave -noupdate -expand -group Wishbone /main/DUT/cmp_ddr3_ctrl_wb_0/wb_stall_o
add wave -noupdate -expand -group Wishbone /main/DUT/cmp_ddr3_ctrl_wb_0/wb_ack_o
add wave -noupdate -expand -group Wishbone /main/DUT/cmp_ddr3_ctrl_wb_0/wb_data_o
add wave -noupdate -expand -group Wishbone /main/DUT/cmp_ddr3_ctrl_wb_0/wb_we_i
add wave -noupdate -expand -group Wishbone /main/DUT/cmp_ddr3_ctrl_wb_0/wb_data_i
add wave -noupdate -expand -group {CMD port} -color Magenta /main/DUT/cmp_ddr3_ctrl_wb_0/cmd_fsm_state
add wave -noupdate -expand -group {CMD port} -color Magenta /main/DUT/cmp_ddr3_ctrl_wb_0/p_cmd_fsm/ddr_burst_cnt
add wave -noupdate -expand -group {CMD port} -color Magenta /main/DUT/cmp_ddr3_ctrl_wb_0/p_cmd_fsm/next_cmd_instr
add wave -noupdate -expand -group {CMD port} -color Magenta /main/DUT/cmp_ddr3_ctrl_wb_0/p_cmd_fsm/next_cmd_bl
add wave -noupdate -expand -group {CMD port} -color Magenta /main/DUT/cmp_ddr3_ctrl_wb_0/p_cmd_fsm/next_cmd_addr
add wave -noupdate -expand -group {CMD port} -color Thistle /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_cmd_instr
add wave -noupdate -expand -group {CMD port} -color Thistle /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_cmd_bl
add wave -noupdate -expand -group {CMD port} -color Thistle /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_cmd_byte_addr
add wave -noupdate -expand -group {CMD port} -color Thistle /main/DUT/cmp_ddr3_ctrl_wb_0/cmd_fifo_we
add wave -noupdate -expand -group {CMD port} -color Thistle /main/DUT/cmp_ddr3_ctrl_wb_0/cmd_fifo_full
add wave -noupdate -expand -group {CMD port} -color Thistle /main/DUT/cmp_ddr3_ctrl_wb_0/cmd_fifo_empty
add wave -noupdate -expand -group {CMD port} -color Thistle /main/DUT/cmp_ddr3_ctrl_wb_0/cmd_fifo_din
add wave -noupdate -expand -group {CMD port} -color Thistle /main/DUT/cmp_ddr3_ctrl_wb_0/cmd_fifo_dout
add wave -noupdate -expand -group {CMD port} -color Thistle /main/DUT/cmp_ddr3_ctrl_wb_0/cmd_fifo_rd_disable
add wave -noupdate -expand -group {CMD port} -color Thistle /main/DUT/cmp_ddr3_ctrl_wb_0/p_cmd_fifo_rd/next_cmd_len
add wave -noupdate -expand -group {CMD port} -color Thistle /main/DUT/cmp_ddr3_ctrl_wb_0/p_cmd_fifo_rd/wr_fifo_cnt
add wave -noupdate -expand -group {CMD port} -color Thistle /main/DUT/cmp_ddr3_ctrl_wb_0/cmd_fifo_rd
add wave -noupdate -expand -group {CMD port} -color {Blue Violet} /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_cmd_en_o
add wave -noupdate -expand -group {CMD port} -color {Blue Violet} /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_cmd_full_i
add wave -noupdate -expand -group {CMD port} -color {Blue Violet} /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_cmd_empty_i
add wave -noupdate -expand -group {CMD port} -color {Blue Violet} /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_cmd_bl_o
add wave -noupdate -expand -group {CMD port} -color {Blue Violet} /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_cmd_byte_addr_o
add wave -noupdate -expand -group {CMD port} -color {Blue Violet} /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_cmd_instr_o
add wave -noupdate -expand -group {RD port} -color Turquoise /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_rd_count_i
add wave -noupdate -expand -group {RD port} -color Turquoise /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_rd_data_i
add wave -noupdate -expand -group {RD port} -color Turquoise /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_rd_empty_i
add wave -noupdate -expand -group {RD port} -color Turquoise /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_rd_en_o
add wave -noupdate -expand -group {RD port} -color Turquoise /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_rd_error_i
add wave -noupdate -expand -group {RD port} -color Turquoise /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_rd_full_i
add wave -noupdate -expand -group {RD port} -color Turquoise /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_rd_overflow_i
add wave -noupdate -expand -group {WR port} -color Wheat /main/DUT/cmp_ddr3_ctrl_wb_0/wr_fifo_we
add wave -noupdate -expand -group {WR port} -color Wheat /main/DUT/cmp_ddr3_ctrl_wb_0/wr_fifo_full
add wave -noupdate -expand -group {WR port} -color Wheat /main/DUT/cmp_ddr3_ctrl_wb_0/wr_fifo_empty
add wave -noupdate -expand -group {WR port} -color Wheat /main/DUT/cmp_ddr3_ctrl_wb_0/wr_fifo_din
add wave -noupdate -expand -group {WR port} -color Wheat /main/DUT/cmp_ddr3_ctrl_wb_0/wr_fifo_dout
add wave -noupdate -expand -group {WR port} -color Wheat /main/DUT/cmp_ddr3_ctrl_wb_0/wr_fifo_rd
add wave -noupdate -expand -group {WR port} -color {Indian Red} /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_wr_en_o
add wave -noupdate -expand -group {WR port} -color {Indian Red} /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_wr_full_i
add wave -noupdate -expand -group {WR port} -color {Indian Red} /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_wr_empty_i
add wave -noupdate -expand -group {WR port} -color {Indian Red} /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_wr_data_o
add wave -noupdate -expand -group {WR port} -color {Indian Red} /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_wr_count_i
add wave -noupdate -expand -group {WR port} -color {Indian Red} /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_wr_underrun_i
add wave -noupdate -expand -group {WR port} -color {Indian Red} /main/DUT/cmp_ddr3_ctrl_wb_0/ddr_wr_error_i
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_dq_b
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_a_o
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_ba_o
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_ras_n_o
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_cas_n_o
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_we_n_o
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_odt_o
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_rst_n_o
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_cke_o
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_dm_o
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_udm_o
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_dqs_p_b
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_dqs_n_b
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_udqs_p_b
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_udqs_n_b
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_clk_p_o
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_clk_n_o
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_rzq_b
add wave -noupdate -group {DDR interface} /main/DUT/ddr3_zio_b
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {2321230250 fs} 0}
quietly wave cursor active 1
configure wave -namecolwidth 336
configure wave -valuecolwidth 100
configure wave -justifyvalue left
configure wave -signalnamewidth 2
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 400000
configure wave -gridperiod 800000
configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ns
update
WaveRestoreZoom {1623922490 fs} {3479833910 fs}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment