Add golden model and instruction generator

This commit is contained in:
Florian Zaruba 2017-05-14 21:12:18 +02:00
parent 851faa7851
commit a6c81e7cab
5 changed files with 179 additions and 2 deletions

View file

@ -18,7 +18,7 @@ envs = $(wildcard tb/env/*/*.sv)
# UVM Sequences
sequences = $(wildcard tb/sequences/*/*.sv)
# Test packages
test_pkg = $(wildcard tb/test/*/*sequence_pkg.sv) $(wildcard tb/test/*/*lib_pkg.sv)
test_pkg = $(wildcard tb/test/*/*_pkg.sv)
# this list contains the standalone components
src = $(wildcard src/util/*.sv) $(wildcard src/*.sv)

View file

@ -18,6 +18,9 @@
// University of Bologna.
//
import ariane_pkg::*;
import fetch_fifo_pkg::*;
module fetch_fifo_tb;
logic rst_ni, clk_i;
@ -59,6 +62,9 @@ module fetch_fifo_tb;
program testbench (fetch_fifo_if fetch_fifo_if);
instruction_stream is = new;
fetch_fifo_model model = new;
initial begin
fetch_fifo_if.mck.flush <= 1'b0;
fetch_fifo_if.mck.in_branch_predict <= 'b0;
@ -67,6 +73,10 @@ module fetch_fifo_tb;
fetch_fifo_if.mck.in_valid <= 'b0;
fetch_fifo_if.mck.out_ready <= 'b0;
forever begin
is.get_instruction();
// @(fetch_fifo_if.mck);
end
end
endprogram

View file

@ -0,0 +1,69 @@
// Author: Florian Zaruba, ETH Zurich
// Date: 14.5.2017
// Description: Fetch FIFO Golden Model
//
//
// 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.
//
// Read 32 bit instruction, separate and re-align them
class fetch_fifo_model;
logic [15:0] unaligned_part;
int is_unaligned = 0;
logic [31:0] instruction_queue[$];
function void put(logic [31:0] instr);
if (is_unaligned == 0) begin
// we've generated a compressed instruction so generate another one
if (instr[1:0] != 2'b11) begin
instruction_queue.push_back({16'b0, instr[15:0]});
if (instr[17:16] == 2'b11) begin
is_unaligned = 1;
unaligned_part = instr[31:16];
end
// normal instruction
end else begin
instruction_queue.push_back(instr);
end
// the last generation iteration produced an outstanding instruction
end else begin
instruction_queue.push_back({instr[15:0], unaligned_part});
if (instr[17:16] != 2'b11) begin
instruction_queue.push_back({16'b0, instr[31:16]});
is_unaligned = 0;
end else begin
// again we have an unaligned instruction
is_unaligned = 1;
unaligned_part = instr[31:16];
end
end
endfunction : put
function logic [31:0] pull();
return instruction_queue.pop_front();
endfunction : pull
function flush();
for (int i = 0; i < instruction_queue.size(); i++) begin
instruction_queue.delete(i);
end
endfunction : flush
endclass : fetch_fifo_model

View file

@ -19,5 +19,6 @@
//
package fetch_fifo_pkg;
`include "instruction_stream.svh"
`include "fetch_fifo_model.svh"
endpackage

View file

@ -0,0 +1,97 @@
// Author: Florian Zaruba, ETH Zurich
// Date: 14.5.2017
// Description: Random instruction class
//
//
// 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.
//
class instruction;
rand logic [31:0] instruction;
rand bit is_compressed;
constraint compressed_constraint {
(is_compressed) -> {
instruction[1:0] != 2'b11;
}
(!is_compressed) -> {
instruction[1:0] == 2'b11;
instruction[4:2] != 3'b111;
}
}
// Return readable representation
function string convert2string();
string s;
$sformat(s, "Instruction: %0h\nCompressed: %h", instruction, is_compressed);
return s;
endfunction : convert2string
endclass : instruction
class instruction_stream;
instruction instr;
logic [15:0] unaligned_part;
int is_unaligned = 0;
// get an instruction stream of consecutive data
function logic [31:0] get_instruction();
logic [31:0] return_instruction;
// generate a new instruction
if (is_unaligned == 0) begin
instr = new;
void'(randomize(instr));
// we've generated a compressed instruction so generate another one
if (instr.is_compressed) begin
return_instruction [15:0] = instr.instruction[15:0];
// get a new instruction
instr = new;
void'(randomize(instr));
return_instruction[31:0] = instr.instruction[15:0];
// $display("Instruction: [ c | c ]");
// was this a compressed instruction as well?
// if not than store that this was an unaligned access
if (!instr.is_compressed) begin
// $display("Instruction: [ i0 | c ]");
is_unaligned = 1;
unaligned_part = instr.instruction[31:16];
end
// normal instruction
end else begin
return_instruction = instr.instruction;
// $display("Instruction: [ i ]");
end
// the last generation iteration produced an outstanding instruction
end else begin
return_instruction [15:0] = unaligned_part;
// generate a new isntruction
instr = new;
void'(randomize(instr));
// was it compressed?
if (instr.is_compressed) begin
return_instruction [31:16] = instr.instruction[15:0];
is_unaligned = 0;
// $display("Instruction: [ c | i1 ]");
end else begin
// again we have an unaligned instruction
unaligned_part = instr.instruction[31:16];
// $display("Instruction: [ i0 | i1 ]");
end
end
return return_instruction;
endfunction : get_instruction
endclass : instruction_stream