testcase framework

This commit is contained in:
Alex Mykyta
2021-11-21 19:00:47 -08:00
parent d3c876a491
commit f70bdf774c
69 changed files with 1730 additions and 403 deletions

View File

View File

@@ -0,0 +1,14 @@
from ..base import CpuifTestMode
from peakrdl.regblock.cpuif.apb3 import APB3_Cpuif, APB3_Cpuif_flattened
class APB3(CpuifTestMode):
cpuif_cls = APB3_Cpuif
tb_files = [
"apb3_intf.sv",
"apb3_intf_driver.sv",
]
tb_template = "tb_inst.sv"
class FlatAPB3(APB3):
cpuif_cls = APB3_Cpuif_flattened

View File

@@ -0,0 +1,40 @@
interface apb3_intf #(
parameter DATA_WIDTH = 32,
parameter ADDR_WIDTH = 32
);
// Command
logic PSEL;
logic PENABLE;
logic PWRITE;
logic [ADDR_WIDTH-1:0] PADDR;
logic [DATA_WIDTH-1:0] PWDATA;
// Response
logic [DATA_WIDTH-1:0] PRDATA;
logic PREADY;
logic PSLVERR;
modport master (
output PSEL,
output PENABLE,
output PWRITE,
output PADDR,
output PWDATA,
input PRDATA,
input PREADY,
input PSLVERR
);
modport slave (
input PSEL,
input PENABLE,
input PWRITE,
input PADDR,
input PWDATA,
output PRDATA,
output PREADY,
output PSLVERR
);
endinterface

View File

@@ -0,0 +1,109 @@
interface apb3_intf_driver #(
parameter DATA_WIDTH = 32,
parameter ADDR_WIDTH = 32
)(
input wire clk,
input wire rst,
apb3_intf.master m_apb
);
timeunit 1ps;
timeprecision 1ps;
logic PSEL;
logic PENABLE;
logic PWRITE;
logic [ADDR_WIDTH-1:0] PADDR;
logic [DATA_WIDTH-1:0] PWDATA;
logic [DATA_WIDTH-1:0] PRDATA;
logic PREADY;
logic PSLVERR;
assign m_apb.PSEL = PSEL;
assign m_apb.PENABLE = PENABLE;
assign m_apb.PWRITE = PWRITE;
assign m_apb.PADDR = PADDR;
assign m_apb.PWDATA = PWDATA;
assign PRDATA = m_apb.PRDATA;
assign PREADY = m_apb.PREADY;
assign PSLVERR = m_apb.PSLVERR;
default clocking cb @(posedge clk);
default input #1step output #1;
output PSEL;
output PENABLE;
output PWRITE;
output PADDR;
output PWDATA;
input PRDATA;
input PREADY;
input PSLVERR;
endclocking
task reset();
cb.PSEL <= '0;
cb.PENABLE <= '0;
cb.PWRITE <= '0;
cb.PADDR <= '0;
cb.PWDATA <= '0;
endtask
task write(logic [ADDR_WIDTH-1:0] addr, logic [DATA_WIDTH-1:0] data);
##0;
// Initiate transfer
cb.PSEL <= '1;
cb.PENABLE <= '0;
cb.PWRITE <= '1;
cb.PADDR <= addr;
cb.PWDATA <= data;
@(cb);
// active phase
cb.PENABLE <= '1;
@(cb);
// Wait for response
while(cb.PREADY !== 1'b1) @(cb);
reset();
endtask
task read(logic [ADDR_WIDTH-1:0] addr, output logic [DATA_WIDTH-1:0] data);
##0;
// Initiate transfer
cb.PSEL <= '1;
cb.PENABLE <= '0;
cb.PWRITE <= '0;
cb.PADDR <= addr;
cb.PWDATA <= '0;
@(cb);
// active phase
cb.PENABLE <= '1;
@(cb);
// Wait for response
while(cb.PREADY !== 1'b1) @(cb);
assert(!$isunknown(cb.PRDATA)) else $error("Read from 0x%0x returned X's on PRDATA", addr);
assert(!$isunknown(cb.PSLVERR)) else $error("Read from 0x%0x returned X's on PSLVERR", addr);
data = cb.PRDATA;
reset();
endtask
task assert_read(logic [ADDR_WIDTH-1:0] addr, logic [DATA_WIDTH-1:0] expected_data);
logic [DATA_WIDTH-1:0] data;
read(addr, data);
assert(data == expected_data) else $error("Read from 0x%x returned 0x%x. Expected 0x%x", addr, data, expected_data);
endtask
initial begin
reset();
end
initial forever begin
@cb;
if(!rst) assert(!$isunknown(cb.PREADY)) else $error("Saw X on PREADY!");
end
endinterface

View File

@@ -0,0 +1,30 @@
apb3_intf #(
.DATA_WIDTH({{exporter.cpuif.data_width}}),
.ADDR_WIDTH({{exporter.cpuif.addr_width}})
) s_apb();
apb3_intf_driver #(
.DATA_WIDTH({{exporter.cpuif.data_width}}),
.ADDR_WIDTH({{exporter.cpuif.addr_width}})
) cpuif(
.clk(clk),
.rst(rst),
.m_apb(s_apb)
);
{% if type(cpuif).__name__.startswith("Flat") %}
wire s_apb_psel;
wire s_apb_penable;
wire s_apb_pwrite;
wire [{{exporter.cpuif.addr_width - 1}}:0] s_apb_paddr;
wire [{{exporter.cpuif.data_width - 1}}:0] s_apb_pwdata;
wire s_apb_pready;
wire [{{exporter.cpuif.data_width - 1}}:0] s_apb_prdata;
wire s_apb_pslverr;
assign s_apb_psel = s_apb.PSEL;
assign s_apb_penable = s_apb.PENABLE;
assign s_apb_pwrite = s_apb.PWRITE;
assign s_apb_paddr = s_apb.PADDR;
assign s_apb_pwdata = s_apb.PWDATA;
assign s_apb.PREADY = s_apb_pready;
assign s_apb.PRDATA = s_apb_prdata;
assign s_apb.PSLVERR = s_apb_pslverr;
{% endif %}

50
test/lib/cpuifs/base.py Normal file
View File

@@ -0,0 +1,50 @@
from typing import List, TYPE_CHECKING
import os
import inspect
import jinja2 as jj
from peakrdl.regblock.cpuif.base import CpuifBase
if TYPE_CHECKING:
from peakrdl.regblock import RegblockExporter
from ..regblock_testcase import RegblockTestCase
class CpuifTestMode:
cpuif_cls = None # type: CpuifBase
tb_files = [] # type: List[str]
tb_template = ""
def get_tb_files(self) -> List[str]:
class_dir = os.path.dirname(inspect.getfile(self.__class__))
cwd = os.getcwd()
tb_files = []
for file in self.tb_files:
relpath = os.path.relpath(
os.path.join(class_dir, file),
cwd
)
tb_files.append(relpath)
return tb_files
def get_tb_inst(self, tb_cls: 'RegblockTestCase', exporter: 'RegblockExporter') -> str:
class_dir = os.path.dirname(inspect.getfile(self.__class__))
loader = jj.FileSystemLoader(
os.path.join(class_dir)
)
jj_env = jj.Environment(
loader=loader,
undefined=jj.StrictUndefined,
)
context = {
"cpuif": self,
"cls": tb_cls,
"exporter": exporter,
"type": type,
}
template = jj_env.get_template(self.tb_template)
return template.render(context)