Add FIFO test incl. CI

This commit is contained in:
Florian Zaruba 2017-04-24 15:35:19 +02:00
parent 7a92b75924
commit 128104dea7
5 changed files with 208 additions and 3 deletions

View file

@ -13,6 +13,17 @@ testALU:
paths:
- covhtmlreport
testFIFO:
stage: test
script:
- make build
- make fifo
- vcover report fifo.ucdb
- vcover report -html fifo.ucdb
artifacts:
paths:
- covhtmlreport
testScoreboard:
stage: test
script:

View file

@ -7,17 +7,17 @@ library = work
# Top level module to compile
top_level = core_tb
test_top_level = core_tb
tests = alu scoreboard
tests = alu scoreboard fifo
# path to agents
agents = tb/agents/fu_if/fu_if.sv tb/agents/fu_if/fu_if_agent_pkg.sv \
include/ariane_pkg.svh tb/agents/scoreboard_if/scoreboard_if.sv tb/agents/scoreboard_if/scoreboard_if_agent_pkg.sv
interfaces = include/debug_if.svh include/mem_if.svh
interfaces = include/debug_if.svh include/mem_if.svh tb/agents/fifo_if/fifo_if.sv
# this list contains the standalone components
src = alu.sv tb/sequences/alu_sequence_pkg.sv tb/env/alu_env_pkg.sv tb/test/alu_lib_pkg.sv tb/alu_tb.sv \
tb/scoreboard_tb.sv \
if_stage.sv compressed_decoder.sv fetch_fifo.sv commit_stage.sv prefetch_buffer.sv \
mmu.sv lsu.sv \
mmu.sv lsu.sv fifo.sv tb/fifo_tb.sv \
scoreboard.sv issue_read_operands.sv decoder.sv id_stage.sv util/cluster_clock_gating.sv regfile.sv ex_stage.sv ariane.sv \
tb/core_tb.sv

22
fifo.sv
View file

@ -50,6 +50,7 @@ module fifo #(
write_pointer_n = write_pointer_q;
status_cnt_n = status_cnt_q;
data_o = mem_q[read_pointer_q];
mem_n = mem_q;
// push a new element to the queue
if (push_i && ~full_o) begin
// push the data onto the queue
@ -67,7 +68,11 @@ module fifo #(
// ... and decrement the overall count
status_cnt_n = status_cnt_q - 1;
end
// keep the count pointer stable if we push and pop at the same time
if (push_i && ~full_o && pop_i && ~empty_o)
status_cnt_n = status_cnt_q;
end
// sequential process
always_ff @(posedge clk_i or negedge rst_ni) begin
if(~rst_ni) begin
@ -82,4 +87,21 @@ module fifo #(
mem_q <= mem_n;
end
end
`ifndef SYNTHESIS
`ifndef verilator
initial begin
assert (DEPTH == 2**$clog2(DEPTH)) else $fatal("FIFO size needs to be a power of two.");
assert property(
@(posedge clk_i) (rst_ni && full_o |-> ~push_i))
else $error ("Trying to push new data although the FIFO is full.");
assert property(
@(posedge clk_i) (rst_ni && empty_o |-> ~pop_i))
else $error ("Trying to pop data although the FIFO is empty.");
`endif
`endif
end
endmodule

47
tb/agents/fifo_if/fifo_if.sv Executable file
View file

@ -0,0 +1,47 @@
// Author: Florian Zaruba, ETH Zurich
// Date: 24.4.2017
// Description: FIFO interface
//
//
// Copyright (C) 2017 ETH Zurich, University of Bologna
// All rights reserved.
//
// This code is under development and not yet released to the public.
// Until it is released, the code is under the copyright of ETH Zurich and
// the University of Bologna, and may contain confidential and/or unpublished
// work. Any reuse/redistribution is strictly forbidden without written
// permission from ETH Zurich.
//
// Bug fixes and contributions will eventually be released under the
// SolderPad open hardware license in the context of the PULP platform
// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the
// University of Bologna.
//
`ifndef FIFO_IF_SV
`define FIFO_IF_SV
interface fifo_if #(parameter type dtype = logic[7:0])
(input clk);
wire full;
wire empty;
dtype wdata;
wire push;
dtype rdata;
wire pop;
clocking mck @(posedge clk);
input full, empty, rdata;
output wdata, push, pop;
endclocking
clocking sck @(posedge clk);
input wdata, push, pop;
output full, empty, rdata;
endclocking
clocking pck @(posedge clk);
input wdata, push, pop, full, empty, rdata;
endclocking
endinterface
`endif

125
tb/fifo_tb.sv Executable file
View file

@ -0,0 +1,125 @@
// Author: Florian Zaruba, ETH Zurich
// Date: 24.4.2017
// Description: FIFO testbench
//
//
// Copyright (C) 2017 ETH Zurich, University of Bologna
// All rights reserved.
//
// This code is under development and not yet released to the public.
// Until it is released, the code is under the copyright of ETH Zurich and
// the University of Bologna, and may contain confidential and/or unpublished
// work. Any reuse/redistribution is strictly forbidden without written
// permission from ETH Zurich.
//
// Bug fixes and contributions will eventually be released under the
// SolderPad open hardware license in the context of the PULP platform
// (http://www.pulp-platform.org), under the copyright of ETH Zurich and the
// University of Bologna.
//
module fifo_tb;
logic rst_ni, clk;
fifo_if #(.dtype ( logic[7:0] )) fifo_if (clk);
logic push, pop;
assign fifo_if.push = ~fifo_if.full & push;
assign fifo_if.pop = ~fifo_if.empty & pop;
fifo
#(.dtype ( logic[7:0] ))
dut
(
.clk_i ( clk ),
.rst_ni ( rst_ni ),
.full_o ( fifo_if.full ),
.empty_o ( fifo_if.empty ),
.data_i ( fifo_if.wdata ),
.push_i ( fifo_if.push ),
.data_o ( fifo_if.rdata ),
.pop_i ( fifo_if.pop )
);
initial begin
clk = 1'b0;
rst_ni = 1'b0;
repeat(8)
#10ns clk = ~clk;
rst_ni = 1'b1;
forever
#10ns clk = ~clk;
end
// simulator stopper, this is suboptimal better go for coverage
initial begin
#10000000ns
$finish;
end
program testbench (fifo_if fifo_if, output logic push, output logic pop);
logic[7:0] queue [$];
// ----------
// Driver
// ----------
initial begin
fifo_if.mck.wdata <= $urandom_range(0,256);
push <= 1'b0;
// wait for reset to be high
wait(rst_ni == 1'b1);
// push
forever begin
repeat($urandom_range(0, 8)) @(fifo_if.mck)
// if there is space lets push some random data
if (~fifo_if.mck.full) begin
fifo_if.mck.wdata <= $urandom_range(0,256);
push <= 1'b1;
end else begin
fifo_if.mck.wdata <= $urandom_range(0,256);
push <= 1'b0;
end
end
end
initial begin
// wait for reset to be high
wait(rst_ni == 1'b1);
// pop from queue
forever begin
@(fifo_if.mck)
pop <= 1'b1;
repeat($urandom_range(0, 8)) @(fifo_if.mck)
pop <= 1'b0;
end
end
// -------------------
// Monitor && Checker
// -------------------
initial begin
automatic logic [7:0] data;
forever begin
@(fifo_if.pck)
if (fifo_if.pck.push) begin
queue.push_back(fifo_if.pck.wdata);
end
if (fifo_if.pck.pop) begin
data = queue.pop_front();
// $display("Time: %t, Expected: %0h Got %0h", $time, data, fifo_if.pck.rdata);
assert(data == fifo_if.mck.rdata) else $error("Mismatch, Expected: %0h Got %0h", data, fifo_if.pck.rdata);
end
end
end
endprogram
testbench tb(fifo_if, push, pop);
endmodule