Commit c6003c76 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

new WB testbench

parent 0144fd39
SOURCES = cgen_c_headers.lua cgen_common.lua cgen_verilog.lua cgen_vhdl.lua target_wishbone.lua wbgen_common.lua wbgen_main.lua wbgen_rams.lua wbgen_regbank.lua wbgen_eic.lua
OUTPUT = wbgen2
all: $(SOURCES)
VHDL_LIBRARY = lib/wbgen2_dpssram.vhd lib/wbgen2_eic.vhd
VERILOG_LIBRARY = $(VHDL_LIBRARY:.vhd=.v)
all: $(SOURCES)
# make -C utils/vhd2vl/src
./utils/process_dofiles.lua wbgen_main.lua wbgen2
chmod +x wbgen2
\ No newline at end of file
chmod +x wbgen2
%.v: %.vhd
./utils/vhd2vl/src/vhd2vl $^ > $@
\ No newline at end of file
......@@ -18,7 +18,15 @@
-- field1_value = FIELD1_R(regs_struct->reg);
--
function cgen_c_field_define(field, reg)
local prefix=string.upper(periph.c_prefix).."_"..string.upper(reg.c_prefix).."_"..string.upper(field.c_prefix);
local prefix;
-- anonymous field?
if(field.c_prefix == nil) then
return ;
else
prefix=string.upper(periph.c_prefix).."_"..string.upper (reg.c_prefix).."_"..string.upper(field.c_prefix);
end
emit("");
emit("/* definitions for field: "..field.name.." in reg: "..reg.name.." */");
......
reg [31:0] wb_addr = 0, wb_data_o = 0;
reg [3:0] wb_bwsel =4'b1111;
wire [31:0] wb_data_i;
wire wb_ack;
reg wb_cyc=0, wb_stb=0, wb_we= 0;
reg wb_tb_verbose = 1;
task wb_verbose;
input onoff;
begin
wb_tb_verbose = onoff;
end
endtask // wb_verbose
task wb_write;
input[31:0] addr;
input [31:0] data;
begin
if(wb_tb_verbose) $display("WB write: addr %x, data %x", addr, data);
wb_stb=1;
wb_cyc=1;
wb_addr = {2'b00, addr[31:2]};
wb_data_o=data;
wb_we = 1;
wb_bwsel = 4'hf;
while(wb_ack == 0) begin @(posedge clk); #1; end
@(posedge clk); #1
wb_cyc = 0;
wb_we=0;
wb_stb=0;
end
endtask // wb_write
task wb_write_byte;
input[31:0] addr;
input [31:0] data;
begin
if(wb_tb_verbose) $display("WB write_byte: addr %x, data %x", addr, data);
wb_stb=1;
wb_cyc=1;
wb_addr ={ 2'b00, addr[31:2] };
wb_data_o= (addr [1:0] == 2'b00) ? {data[7:0], 24'bx} :
(addr [1:0] == 2'b01) ? {8'bx, data[7:0], 16'bx} :
(addr [1:0] == 2'b10) ? {16'bx, data[7:0], 8'bx} :
(addr [1:0] == 2'b11) ? {24'bx, data[7:0]} : 32'bx;
wb_we = 1;
wb_bwsel = (addr [1:0] == 2'b00) ? 'b1000 :
(addr [1:0] == 2'b01) ? 'b0100 :
(addr [1:0] == 2'b10) ? 'b0010 :
(addr [1:0] == 2'b11) ? 'b0001 : 4'bxxxx;
while(wb_ack == 0) begin @(posedge clk); #1; end
@(posedge clk); #1;
wb_cyc = 0;
wb_we=0;
wb_stb=0;
end
endtask // wb_write
task wb_read;
input[31:0] addr;
output [31:0] data;
begin
wb_bwsel=4'hf;
wb_stb=1;
wb_cyc=1;
wb_addr = {2'b00, addr[31:2]};
wb_data_o=data;
wb_we = 0;
while(wb_ack == 0) @(posedge clk);
#1 data = wb_data_i;
@(posedge clk);
wb_cyc = 0;
wb_we=0;
wb_stb=0;
if(wb_tb_verbose) $display("WB read: addr %x data %x", addr, data);
end
endtask // wb_read
task wb_read_byte;
input[31:0] addr;
output [31:0] data;
begin : task_wb_read_byte
reg [31:0] data_tmp;
wb_bwsel=4'hf;
wb_stb=1;
wb_cyc=1;
wb_addr = {2'b00, addr[31:2]};
wb_data_o=data;
wb_we = 0;
while(wb_ack == 0) @(posedge clk);
#1 data = (addr [1:0] == 2'b00) ? wb_data_i[31:24] :
(addr [1:0] == 2'b01) ? wb_data_i[23:16] :
(addr [1:0] == 2'b10) ? wb_data_i[15:8] :
(addr [1:0] == 2'b11) ? wb_data_i[7:0] : 4'bxxxx;
@(posedge clk);
wb_cyc = 0;
wb_we=0;
wb_stb=0;
if(wb_tb_verbose) $display("WB read byte: addr %x data %x", addr, data);
end
endtask // wb_read
\ No newline at end of file
//
// Title : Software Wishbone master unit for testbenches
//
// File : wishbone_master_tb.v
// Author : Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
// Created : Tue Mar 23 12:19:36 2010
// Standard : Verilog 2001
//
// Default values of certain WB parameters.
// Bus clock period
`ifndef WB_CLOCK_PERIOD
`define WB_CLOCK_PERIOD 100
`define WB_RESET_DELAY (3*`WB_CLOCK_PERIOD)
`endif
// Widths of wishbone address/data/byte select
`ifndef WB_DATA_BUS_WIDTH
`define WB_DATA_BUS_WIDTH 32
`endif
`ifndef WB_ADDRESS_BUS_WIDTH
`define WB_ADDRESS_BUS_WIDTH 32
`endif
`define WB_BWSEL_WIDTH ((`WB_DATA_BUS_WIDTH + 7) / 8)
module WB_TEST_MASTER;
// these signals make the WB bus, which can be accessed from outside the module
reg [`WB_ADDRESS_BUS_WIDTH - 1 : 0] wb_addr = 0;
reg [`WB_DATA_BUS_WIDTH - 1 : 0] wb_data_o = 0;
reg [`WB_BWSEL_WIDTH - 1 : 0] wb_bwsel = 0;
wire [`WB_DATA_BUS_WIDTH -1 : 0] wb_data_i;
wire wb_ack;
reg wb_cyc = 0;
reg wb_stb = 0;
reg wb_we = 0;
reg wb_rst = 0;
reg wb_clk = 1;
reg wb_tb_verbose = 1;
reg wb_monitor_bus = 1;
time last_access_t = 0;
reg [`WB_DATA_BUS_WIDTH -1 : 0] dummy;
// ready signal. 1 indicates that WB_TEST unit is initialized and ready for commands
reg ready = 0;
// generate the WB bus clock
always #(`WB_CLOCK_PERIOD/2) wb_clk <= ~wb_clk;
// generate the reset and ready signals
initial begin
#(`WB_RESET_DELAY) wb_rst <= 1;
#(`WB_CLOCK_PERIOD*2) ready <= 1;
end
// enables/disables displaying information about each read/write operation.
task verbose;
input onoff;
begin
wb_tb_verbose = onoff;
end
endtask // wb_verbose
task monitor_bus;
input onoff;
begin
wb_monitor_bus = onoff;
end
endtask // monitor_bus
task rw_generic;
input [`WB_ADDRESS_BUS_WIDTH - 1 : 0] addr;
input [`WB_DATA_BUS_WIDTH - 1 : 0] data_i;
output [`WB_DATA_BUS_WIDTH - 1 : 0] data_o;
input rw;
input [3:0] size;
begin : rw_generic_main
if(wb_tb_verbose && rw)
$display("WB write %s: addr %x, data %x",
(size==1?"byte":((size==2)?"short":"int")),
addr, data_i);
if($time != last_access_t) begin
@(posedge wb_clk);
end
wb_stb<=1;
wb_cyc<=1;
wb_addr <= {2'b00, addr[31:2]};
wb_we <= rw;
if(rw) begin
case(size)
4: begin wb_data_o<=data_i; wb_bwsel <= 4'b1111; end
2: begin
if(addr[1]) begin
wb_data_o[31:16] = data_i[15:0];
wb_bwsel = 4'b1100;
end else begin
wb_data_o[15:0] = data_i[15:0];
wb_bwsel = 4'b0011;
end
end
1: begin
case(addr[1:0])
0: begin wb_data_o[31:24] = data_i[7:0]; wb_bwsel <= 4'b1000; end
1: begin wb_data_o[23:16] = data_i[7:0]; wb_bwsel <= 4'b0100; end
2: begin wb_data_o[15:8] = data_i[7:0]; wb_bwsel <= 4'b0010; end
3: begin wb_data_o[7:0] = data_i[7:0]; wb_bwsel <= 4'b0001; end
endcase // case(addr[1:0])
end
endcase // case(size)
end // if (rw)
#(`WB_CLOCK_PERIOD-1);
if(wb_ack == 0) begin
while(wb_ack == 0) begin @(posedge wb_clk); end
end
data_o = wb_data_i;
wb_cyc <= 0;
wb_we<=0;
wb_stb<=0;
if(wb_tb_verbose && !rw)
$display("WB read %s: addr %x, data %x",
(size==1?"byte":((size==2)?"short":"int")),
addr, wb_data_i);
last_access_t = $time;
end
endtask // rw_generic
task write8;
input [`WB_ADDRESS_BUS_WIDTH - 1 : 0] addr;
input [7 : 0] data_i;
begin
rw_generic(addr, data_i, dummy, 1, 1);
end
endtask // write8
task read8;
input [`WB_ADDRESS_BUS_WIDTH - 1 : 0] addr;
output [7 : 0] data_o;
begin : read8_body
reg [`WB_DATA_BUS_WIDTH - 1 : 0] rval;
rw_generic(addr, 0, rval, 0, 1);
data_o = rval[7:0];
end
endtask // write8
task write32;
input [`WB_ADDRESS_BUS_WIDTH - 1 : 0] addr;
input [31 : 0] data_i;
begin
rw_generic(addr, data_i, dummy, 1, 4);
end
endtask // write32
task read32;
input [`WB_ADDRESS_BUS_WIDTH - 1 : 0] addr;
output [31 : 0] data_o;
begin : read32_body
reg [`WB_DATA_BUS_WIDTH - 1 : 0] rval;
rw_generic(addr, 0, rval, 0, 4);
data_o = rval[31:0];
end
endtask // write32
// bus monitor
always@(posedge wb_clk) begin
if(wb_monitor_bus && wb_cyc && wb_stb && wb_ack)begin
if(wb_we) $display("ACK-Write: addr %x wdata %x bwsel %b", wb_addr, wb_data_o, wb_bwsel);
else $display("ACK-Read: addr %x rdata %x", wb_addr, wb_data_i);
end
end
endmodule
\ No newline at end of file
......@@ -802,6 +802,6 @@ XML_DoubleClick = Edit
XML_CustomDoubleClick =
LOGFILE_DoubleClick = Edit
LOGFILE_CustomDoubleClick =
EditorState = {tabbed horizontal 1}
EditorState = {tabbed horizontal 1} {/home/slayer/wbgen2_svn/wbgen2/examples/gpio_port/run.do 0 0}
Project_Major_Version = 6
Project_Minor_Version = 2
set input_wb_file "gpio_port.wb"
set test_module "gpio_port"
set target "classic"
set lang "vhdl"
set library_files {}
set extra_files { "gpio_port.vhd" };
mkdir -p ./output
vlib work
vlib wbgen2
../../wbgen2.lua gpio_port.wb -vo ./output/wb_slave_gpio_port.vhdl -consto ./output/vlog_constants.v
foreach file $library_files { vcom -work wbgen2 $file }
foreach file $extra_files { vcom -work work $file }
if { $lang == "vhdl" } {
set target_filename [format "./output/%s.vhd" $test_module ]
set target_wb "+define+WB_USE_CLASSIC"
set wbgen_opt "-target classic"
} else {
set target_filename [format "./output/%s.v" $test_module ]
set target_wb "+define+WB_USE_PIPELINED"
set wbgen_opt "-target pipelined"
}
puts $target_filename
vcom ./output/wb_slave_gpio_port.vhdl
vcom ./gpio_port.vhdl
vlog ./testbench.v
../../wbgen2 $input_wb_file -vo $target_filename -consto ./output/vlog_constants.v -co ./output/regdefs.h -lang $lang $wbgen_opt
if { $lang == "verilog" } {
vlog -work work -work wbgen2 $target_filename
} else {
vcom -work work $target_filename
}
vlog ./testbench.v
vsim work.main
radix -hexadecimal
do wave.do
run 15us
run 100us
wave zoomfull
`timescale 1ns/1ps
`define wbclk_period 100
`include "output/vlog_constants.v"
`include "../common/wishbone_test_master.v"
module main;
reg clk=1;
reg rst=0;
wire [3:0] ones = 'b1111;
always #(`wbclk_period/2) clk <= ~clk;
initial #1000 rst <= 1;
`include "wishbone_stuff.v"
wire [31:0] gpio_pins_b;
reg [31:0] gpio_reg = 32'bz;
gpio_port dut(
WB_TEST_MASTER WB();
wire [31:0] gpio_pins_b;
reg [31:0] gpio_reg = 32'bz;
.rst_n_i (rst),
.wb_clk_i (clk),
.wb_addr_i (wb_addr[2:0]),
.wb_data_i (wb_data_o),
.wb_data_o (wb_data_i),
.wb_cyc_i (wb_cyc),
.wb_stb_i (wb_stb),
.wb_we_i (wb_we),
.wb_ack_o (wb_ack),
.wb_sel_i(ones),
wire clk = WB.wb_clk;
wire rst = WB.wb_rst;
.gpio_pins_b (gpio_pins_b)
);
gpio_port dut(
assign gpio_pins_b = gpio_reg;
.rst_n_i (WB.wb_rst),
.wb_clk_i (WB.wb_clk),
.wb_addr_i (WB.wb_addr[2:0]),
.wb_data_i (WB.wb_data_o),
.wb_data_o (WB.wb_data_i),
.wb_cyc_i (WB.wb_cyc),
.wb_stb_i (WB.wb_stb),
.wb_we_i (WB.wb_we),
.wb_sel_i (WB.wb_bwsel),
.wb_ack_o (WB.wb_ack),
.gpio_pins_b (gpio_pins_b)
);
assign gpio_pins_b = gpio_reg;
reg[31:0] data;
reg [31:0] data;
integer i;
initial begin
#2001; // wait until the DUT is reset
$display("Set half of the pins to outputs, other half to inputs");
wb_write(`ADDR_GPIO_DDR, 32'hffff0000);
wait (WB.ready);
$display("Set half of the pins to outputs, other half to inputs");
WB.write32(`ADDR_GPIO_DDR, 32'hffff0000);
$display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
$display("Set every even byte to '1'");
wb_write(`ADDR_GPIO_SOPR, 32'hff00ff00);
$display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
#1 $display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
$display("Set every even byte to '1'");
WB.write32(`ADDR_GPIO_SOPR, 32'hff00ff00);
#1 $display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
$display("Clear every even bit");
wb_write(`ADDR_GPIO_COPR, 32'h55555555);
$display("Clear every even bit");
WB.write32(`ADDR_GPIO_COPR, 32'h55555555);
$display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
$display("Write an arbitrary value");
wb_write(`ADDR_GPIO_PDR, 32'hdeadbeef);
$display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
$display("Force something tasty on the GPIO input pins");
gpio_reg[15:0] = 16'hcafe;
#1 $display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
delay_cycles(1);
$display("Write an arbitrary value");
WB.write32(`ADDR_GPIO_PDR, 32'hdeadbeef);
$display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
delay_cycles(10); // wait for a while for the sync logic
wb_read(`ADDR_GPIO_PSR, data);
$display("Time for %x!", data[15:0]);
#1 $display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
end
$display("Force something tasty on the GPIO input pins");
gpio_reg[15:0] = 16'hcafe;
#1 $display("Pins state: %b (%x)", gpio_pins_b, gpio_pins_b);
#1000; // wait for a while (sync logic)
WB.read32(`ADDR_GPIO_PSR, data);
$display("Time for %x!", data[15:0]);
end
endmodule
reg [31:0] wb_addr, wb_data_o, tmp;
wire [31:0] wb_data_i;
wire wb_ack;
reg wb_sel =0, wb_cyc=0, wb_stb=0, wb_we= 0;
task delay_cycles;
input [31:0] n;
begin
#(n * `wbclk_period);
end
endtask // delay_cycles
task wb_write;
input[31:0] addr;
input [31:0] data;
begin
$display("WB write: addr %x, data %x", addr, data);
wb_sel=1;
wb_stb=1;
wb_cyc=1;
wb_addr = addr;
wb_data_o=data;
wb_we = 1;
delay_cycles(1);
while(wb_ack == 0)
delay_cycles(1);
delay_cycles(1);
wb_cyc = 0;
wb_sel=0;
wb_we=0;
wb_stb=0;
end
endtask // wb_write
task wb_read;
input[31:0] addr;
output [31:0] data;
begin
wb_sel=1;
wb_stb=1;
wb_cyc=1;
wb_addr = addr;
wb_data_o=data;
wb_we = 0;
delay_cycles(1);
while(wb_ack == 0)
delay_cycles(1);
data = wb_data_i;
delay_cycles(1);
wb_cyc = 0;
wb_sel=0;
wb_we=0;
wb_stb=0;
end
endtask // wb_read
......@@ -804,6 +804,6 @@ XML_DoubleClick = Edit
XML_CustomDoubleClick =
LOGFILE_DoubleClick = Edit
LOGFILE_CustomDoubleClick =
EditorState = {tabbed horizontal 1} {/home/slayer/wbgen2_svn/wbgen2/examples/interrupts/run.do 0 0}
EditorState = {tabbed horizontal 1} {/home/slayer/wbgen2_svn/wbgen2/examples/interrupts/run.do 0 1}
Project_Major_Version = 6
Project_Minor_Version = 2
set input_wb_file "interrupts.wb"
set test_module "wb_test_interrupts"
set target "classic"
set lang "vhdl"
set library_files {
"../../lib/wbgen2_pkg.vhd"
"../../lib/wbgen2_eic.vhd"
};
vlib work
vlib wbgen2
../../wbgen2 interrupts.wb -vo ./output/wb_test_interrupts.vhd -consto ./output/vlog_constants.v -co ./output/test_interupts.h
foreach file $library_files { vcom -work wbgen2 $file }
if { $lang == "vhdl" } {
set target_filename [format "./output/%s.vhd" $test_module ]
set target_wb "+define+WB_USE_CLASSIC"
set wbgen_opt "-target classic"
} else {
set target_filename [format "./output/%s.v" $test_module ]
set target_wb "+define+WB_USE_PIPELINED"
set wbgen_opt "-target pipelined"
}
puts $target_filename
../../wbgen2 $input_wb_file -vo $target_filename -consto ./output/vlog_constants.v -co ./output/regdefs.h -lang $lang $wbgen_opt
vcom -work wbgen2 ../../lib/wbgen2_pkg.vhd
vcom -work wbgen2 ../../lib/wbgen2_eic.vhd
vcom -work work ./output/wb_test_interrupts.vhd
if { $lang == "verilog" } {
vlog -work work -work wbgen2 $target_filename
} else {
vcom -work work $target_filename
}
vlog ./testbench.v
......@@ -15,6 +41,6 @@ radix -hexadecimal
do wave.do
run 50us
run 100us
wave zoomfull
`timescale 1ns/1ps
// Testbench for Embedded Interrupt Controller (EIC) wbgen2 functionatlity
`define wbclk_period 100
`define async_clk_period 63
`timescale 1ns/1ps
`include "../common/wishbone_test_master.v"
`include "output/vlog_constants.v"
module main;
reg clk=1;
reg ram1_clk = 1;
reg [31:0] rval;