1
0
mirror of https://github.com/aolofsson/oh.git synced 2025-01-17 20:02:53 +08:00
oh/common/dv/stimulus.v
2016-01-10 11:57:38 -05:00

168 lines
4.4 KiB
Verilog

/*
* Reads transctions from file in Epiphany Memory Format (EMF) and drives
* packet output.
*
* NOTE: wait comes in one next cycle, this block adjusts for that!
*
*/
`timescale 1ns/1ps
module stimulus (/*AUTOARG*/
// Outputs
stim_access, stim_packet, stim_count, stim_done, stim_wait,
// Inputs
clk, nreset, start, dut_wait
);
//stimulus
parameter PW = 32; //size of packet
parameter MAW = 15;
parameter MD = 1<<MAW; //limit test to 1K transactions
parameter INDEX = 1;
parameter NAME = "not_declared";
parameter WAIT = 0;
//Inputs
input clk;
input nreset;
input start;
input dut_wait;
//outputs
output stim_access;
output [PW-1:0] stim_packet;
output [31:0] stim_count;
output stim_done;
output stim_wait;
//variables
reg mem_access;
reg [PW+16-1:0] stimarray[MD-1:0];
reg [PW+16-1:0] mem_data;
reg [MAW-1:0] stim_addr;
reg [1:0] state;
reg [31:0] stim_count;
reg [15:0] wait_counter;
reg [PW-1:0] stim_packet_reg;
reg stim_access_reg;
//Read in stimulus
integer i,j;
reg [255:0] testfile;
integer fd;
reg [128*8:0] str;
reg [31:0] stim_end;
wire stall_random;
//Read Stimulus
initial begin
$sformat(testfile[255:0],"%0s_%0d%s",NAME,INDEX,".emf");
fd = $fopen(testfile, "r");
if(!fd)
begin
$display("could not open the file %0s\n", testfile);
$finish;
end
//Read stimulus from file
j=0;
while ($fgets(str, fd)) begin
if ($sscanf(str,"%h", stimarray[j]))
begin
//$display("%0s %0d data=%0h", testfile, j, stimarray[j]);
j=j+1;
end
end
stim_end[31:0]=j;
end
`define IDLE 2'b00
`define DONE 2'b10
`define GO 2'b01
always @ (posedge clk or negedge nreset)
if(!nreset)
begin
state[1:0] <= `IDLE;
mem_access <= 1'b0;
mem_data <= 'd0;
stim_count <= 0;
stim_addr[MAW-1:0] <= 'b0;
wait_counter <= 'b0;
end
else if(start & (state[1:0]==`IDLE))//not started
begin
state[1:0] <= `GO;//going
end
else if((wait_counter[15:0]==0) & (stim_count < stim_end) & (state[1:0]==`GO) & ~dut_wait)//going
begin
wait_counter[15:0] <= stimarray[stim_addr];//first 15 bits
mem_data[PW+16-1:0] <= stimarray[stim_addr];//FIX: used 2D indexiing?
mem_access <= 1'b1;
stim_addr[MAW-1:0] <= stim_addr[MAW-1:0] + 1'b1;
stim_count <= stim_count + 1'b1;
end
else if((wait_counter[15:0]==0) & (stim_count == stim_end) & (state[1:0]==`GO) & ~dut_wait) //not waiting and done
begin
state[1:0] <= `DONE;//gone
mem_access <= 1'b0;
end
else if(wait_counter>0)
begin
mem_access <= 1'b0;
wait_counter[15:0] <= wait_counter[15:0] - 1'b1;
end
//Use to finish simulation
assign stim_done = ~dut_wait & (state[1:0]==`DONE);
//Removing delay value
//assign stim_packet[PW-1:0] = mem_data[PW+16-1:
always @ (posedge clk or negedge nreset)
if(~nreset)
begin
stim_packet_reg <= 'b0;
stim_access_reg <= 'b0;
end
else if(~dut_wait)
begin
stim_packet_reg <= mem_data[PW+16-1:16];
stim_access_reg <= mem_access;
end
assign stim_packet = dut_wait ? stim_packet_reg : mem_data[PW+16-1:16];
//assign stim_access = dut_wait ? stim_access_reg : mem_access;
assign stim_access = dut_wait ? 1'b0 : mem_access;
//TODO: Implement
//lfsr?
//seed from command line?
//walk through the waits:0,1,2,3,4,5,6,7,8,16,32,64,128 cycles
//randomize where you start in state machine
assign stim_wait = stall_random;
//Random wait generator
//TODO: make this a module
generate
if(WAIT)
begin
reg [15:0] stall_counter;
always @ (posedge clk or negedge nreset)
if(!nreset)
stall_counter[15:0] <= 'b0;
else
stall_counter[15:0] <= stall_counter+1'b1;
assign stall_random = (|stall_counter[6:0]);//(|wait_counter[3:0]);//1'b0;
end
else
begin
assign stall_random = 1'b0;
end // else: !if(WAIT)
endgenerate
endmodule // stimulus