Add mapper and testbench
This commit is contained in:
@@ -116,3 +116,17 @@ full sim:
|
|||||||
dependencies:
|
dependencies:
|
||||||
- build toolchain
|
- build toolchain
|
||||||
|
|
||||||
|
mapper sim:
|
||||||
|
tags:
|
||||||
|
- linux
|
||||||
|
- iverilog
|
||||||
|
stage: simulate
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- hw/efinix_fpga/simulation/mapper_tb.vcd
|
||||||
|
script:
|
||||||
|
- source init_env.sh
|
||||||
|
- cd hw/efinix_fpga/simulation
|
||||||
|
- make clean
|
||||||
|
- make mapper_tb
|
||||||
|
- ./mapper_tb
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
SRCS=$(shell find src/ -type f -name "*.*v")
|
SRCS=$(shell find src/ -type f -name "*.*v")
|
||||||
|
TBS=$(shell find tbs/ -type f -name "*.*v")
|
||||||
SRCS+=$(shell find ../ip/ -type f -name "*.*v" -not \( -name "*tmpl*" \))
|
SRCS+=$(shell find ../ip/ -type f -name "*.*v" -not \( -name "*tmpl*" \))
|
||||||
SRCS+=$(shell find ../src/ -type f -name "*.*v")
|
SRCS+=$(shell find ../src/ -type f -name "*.*v")
|
||||||
|
|
||||||
@@ -28,6 +29,9 @@ sim: $(TARGET)
|
|||||||
full_sim: $(TARGET) $(SD_IMAGE)
|
full_sim: $(TARGET) $(SD_IMAGE)
|
||||||
vvp $(TARGET) -fst
|
vvp $(TARGET) -fst
|
||||||
|
|
||||||
|
mapper_tb: $(SRCS) $(TBS)
|
||||||
|
iverilog -g2005-sv $(FLAGS) -s $@ -o $@ $(INC) $(SRCS) $(TBS)
|
||||||
|
|
||||||
|
|
||||||
$(TARGET): $(INIT_MEM) $(SRCS)
|
$(TARGET): $(INIT_MEM) $(SRCS)
|
||||||
iverilog -g2005-sv $(FLAGS) -s $(TOP_MODULE) -o $(TARGET) $(INC) $(SRCS)
|
iverilog -g2005-sv $(FLAGS) -s $(TOP_MODULE) -o $(TARGET) $(INC) $(SRCS)
|
||||||
@@ -46,3 +50,5 @@ clean:
|
|||||||
rm -rf $(TARGET)
|
rm -rf $(TARGET)
|
||||||
rm -rf $(INIT_MEM)
|
rm -rf $(INIT_MEM)
|
||||||
rm -rf $(SD_IMAGE)
|
rm -rf $(SD_IMAGE)
|
||||||
|
rm -rf mapper_tb
|
||||||
|
rm -rf mapper_tb.vcd
|
||||||
|
|||||||
100
hw/efinix_fpga/simulation/tbs/mapper_tb.sv
Normal file
100
hw/efinix_fpga/simulation/tbs/mapper_tb.sv
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
`timescale 1ns/1ps
|
||||||
|
|
||||||
|
module mapper_tb();
|
||||||
|
|
||||||
|
logic r_clk_cpu;
|
||||||
|
|
||||||
|
// clk_cpu
|
||||||
|
initial begin
|
||||||
|
r_clk_cpu <= '1;
|
||||||
|
forever begin
|
||||||
|
#125 r_clk_cpu <= ~r_clk_cpu;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
logic reset;
|
||||||
|
logic [15:0] addr;
|
||||||
|
logic [24:0] map_addr;
|
||||||
|
logic [7:0] i_data;
|
||||||
|
logic [7:0] o_data;
|
||||||
|
logic cs;
|
||||||
|
logic rwb;
|
||||||
|
|
||||||
|
mapper u_mapper(
|
||||||
|
.i_reset(reset),
|
||||||
|
.i_clk(r_clk_cpu),
|
||||||
|
.i_cs(cs),
|
||||||
|
.i_we(~rwb),
|
||||||
|
.i_data(i_data),
|
||||||
|
.o_data(o_data),
|
||||||
|
.i_cpu_addr(addr),
|
||||||
|
.o_mapped_addr(map_addr)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/* These could be made better probably */
|
||||||
|
task write_reg(input logic [4:0] _addr, input logic [7:0] _data);
|
||||||
|
@(negedge r_clk_cpu);
|
||||||
|
cs <= '1;
|
||||||
|
addr <= _addr;
|
||||||
|
rwb <= '0;
|
||||||
|
i_data <= '1;
|
||||||
|
@(posedge r_clk_cpu);
|
||||||
|
i_data <= _data;
|
||||||
|
@(negedge r_clk_cpu);
|
||||||
|
cs <= '0;
|
||||||
|
rwb <= '1;
|
||||||
|
endtask
|
||||||
|
|
||||||
|
task read_reg(input logic [2:0] _addr, output logic [7:0] _data);
|
||||||
|
@(negedge r_clk_cpu);
|
||||||
|
cs <= '1;
|
||||||
|
addr <= _addr;
|
||||||
|
rwb <= '1;
|
||||||
|
i_data <= '1;
|
||||||
|
@(posedge r_clk_cpu);
|
||||||
|
_data <= o_data;
|
||||||
|
@(negedge r_clk_cpu);
|
||||||
|
cs <= '0;
|
||||||
|
rwb <= '1;
|
||||||
|
endtask
|
||||||
|
|
||||||
|
int errors;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
errors = 0;
|
||||||
|
repeat (5) @(posedge r_clk_cpu);
|
||||||
|
reset = 1;
|
||||||
|
cs = 0;
|
||||||
|
rwb = 1;
|
||||||
|
addr = '0;
|
||||||
|
i_data = '0;
|
||||||
|
repeat (5) @(posedge r_clk_cpu);
|
||||||
|
reset = 0;
|
||||||
|
repeat (5) @(posedge r_clk_cpu);
|
||||||
|
|
||||||
|
write_reg(0, 8'haa);
|
||||||
|
write_reg(1, 8'hbb);
|
||||||
|
|
||||||
|
repeat (5) @(posedge r_clk_cpu);
|
||||||
|
|
||||||
|
assert (u_mapper.mm[0] == 16'hbbaa) else begin
|
||||||
|
$error("mm[0] expected 0xbbaa got 0x%x", u_mapper.mm[0]);
|
||||||
|
errors += 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
if (errors != 0) begin
|
||||||
|
$finish_and_return(-1);
|
||||||
|
end else begin
|
||||||
|
$finish();
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
initial
|
||||||
|
begin
|
||||||
|
$dumpfile("mapper_tb.vcd");
|
||||||
|
$dumpvars(0,mapper_tb);
|
||||||
|
for (int i = 0; i < 16; i++) $dumpvars(0, u_mapper.mm[i]);
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
40
hw/efinix_fpga/src/mapper.sv
Normal file
40
hw/efinix_fpga/src/mapper.sv
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
module mapper(
|
||||||
|
input i_reset,
|
||||||
|
input i_clk,
|
||||||
|
input i_cs,
|
||||||
|
input i_we,
|
||||||
|
input [7:0] i_data,
|
||||||
|
output logic [7:0] o_data,
|
||||||
|
input [15:0] i_cpu_addr,
|
||||||
|
output logic [24:0] o_mapped_addr
|
||||||
|
);
|
||||||
|
|
||||||
|
logic [15:0] mm [16];
|
||||||
|
|
||||||
|
logic [31:0] we;
|
||||||
|
|
||||||
|
logic [15:0] mm_sel;
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
we = (i_we << i_cpu_addr[4:0]);
|
||||||
|
|
||||||
|
o_data = mm_sel[8*i_cpu_addr[0] +: 8];
|
||||||
|
end
|
||||||
|
|
||||||
|
always_ff @(negedge i_clk or posedge i_reset) begin
|
||||||
|
if (i_reset) begin
|
||||||
|
for (int i = 0; i < 16; i++) begin
|
||||||
|
mm[i] <= i;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for (int i = 0; i < 31; i++) begin
|
||||||
|
if (we[i]) begin
|
||||||
|
mm[i/2][(i%2)*8 +: 8] <= i_data;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
Reference in New Issue
Block a user