sai685
Junior Member level 2
give me the testbench in systemverilog for the following code which is OCX transmitter and receiver
Code:
// this is receiver code
//
//
//`include "ocx_pkg.sv"
module ocx_rx(
input port ocx_in,
input rst_n, clk,
output logic valid, error,
output logic [511:0]data_out_512,
output logic [5:0]eop_ptr_6
);
logic [7:0] buffer[64];
logic [7:0] clk_count;
logic [6:0] data_count;
logic clk_count_en, clk_count_rst, data_count_en, data_count_rst, data_load, data_store, data_count_prst, clk_count_prst;
logic temp_error;
typedef enum {IDLE, RX, WAIT} state;
state cur_state, next_state;
always_ff @ (posedge clk or negedge rst_n)
if(!rst_n)
cur_state<=IDLE;
else
cur_state<=next_state;
always_comb
begin
clk_count_en = 0;
clk_count_rst = 0;
data_count_en = 0;
data_count_rst = 0;
data_load = 0;
data_store = 0;
eop_ptr_6 = 0;
error = 0;
valid = 0;
data_count_prst = 0;
clk_count_prst = 0;
case(cur_state)
IDLE:
begin
temp_error = 0;
if(ocx_in.sop && ocx_in.valid && !ocx_in.eop)
begin
data_count_en = 1;
clk_count_en = 1;
data_store = 1;
next_state = RX;
end
else
begin
clk_count_rst = 1;
data_count_rst = 1;
next_state = IDLE;
end
end
RX:
begin
if(!ocx_in.sop && !ocx_in.eop && ocx_in.valid && clk_count < 128 && data_count < 64 )
begin
data_count_en = 1;
clk_count_en = 1;
data_store = 1;
next_state = RX;
end
else if(ocx_in.sop && !ocx_in.eop && ocx_in.valid && clk_count == 1 && data_count == 1 )
begin
data_count_en = 1;
clk_count_en = 1;
data_store = 1;
next_state = RX;
end
else if(!ocx_in.sop && !ocx_in.eop && !ocx_in.valid && clk_count < 128 && data_count < 64 )
begin
data_count_en = 0;
clk_count_en = 1;
data_store = 0;
next_state = RX;
end
else if(!ocx_in.sop && ocx_in.eop && ocx_in.valid )
begin
data_count_en = 1;
clk_count_en = 1;
data_store = 1;
next_state = WAIT;
end
else
begin
if(valid)
begin
data_count_en = 1;
data_store = 1;
end
clk_count_en = 1;
temp_error = 1;
next_state = RX;
end
end
WAIT:
begin
if(ocx_in.sop && ocx_in.valid &&!ocx_in.eop )
begin
temp_error = 1;
data_count_prst = 1;
clk_count_prst = 1;
data_store = 1;
next_state = RX;
end
else
begin
clk_count_rst = 1;
data_count_rst = 1;
data_load = 1;
eop_ptr_6 = data_count - 1;
error = temp_error;
next_state = IDLE;
valid = 1;
end
end
endcase
end
// clock counter
always_ff @ (posedge clk or negedge rst_n)
begin
if(!rst_n || clk_count_rst)
begin
clk_count<=0;
end
else if(clk_count_prst)
clk_count<=1;
else
begin
clk_count<=clk_count;
if(clk_count_en)
clk_count<=clk_count+1;
end
end
// data counter
always_ff @ (posedge clk or negedge rst_n)
begin
if(!rst_n || data_count_rst)
begin
data_count <=0;
end
else if(data_count_prst)
data_count <= 1;
else
begin
data_count <= data_count;
if(data_count_en)
data_count <= data_count+1;
end
end
// data register
always_ff @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
buffer <= '{64{8'b0}};
end
else if(data_store && data_count_prst)
begin
buffer[0] <= ocx_in.data_8;
end
else if(data_store)
begin
buffer[data_count] <= ocx_in.data_8;
end
end
always_comb
begin
if(!rst_n)
begin
data_out_512=0;
end
else if(data_load)
begin
for(int i=0; i<data_count; i++)
begin
data_out_512 = {data_out_512,buffer[i]};
end
end
end
endmodule
Code:
// THIS IS TRANSMITTER CODE
//
//
//`include "ocx_pkg.sv"
module ocx_tx(
input logic rst_n, clk,
input logic valid, error,
input logic [511:0]data_in_512,
input logic [5:0]eop_ptr_6,
output port ocx_out
);
logic [511:0] buffer[256];
logic [5:0] temp_ptr[256];
logic [7:0] ptr_count;
logic [6:0] data_count;
logic temp_error[256];
logic temp_valid[256];
logic data_count_en, data_count_rst, data_load, data_store, ptr_count_en, ptr_count_rst;
int i ;
typedef enum {IDLE,TX} state;
state cur_state, next_state;
always_ff @ (posedge clk or negedge rst_n)
if(!rst_n)
cur_state<=IDLE;
else
cur_state<=next_state;
always_comb
begin
data_count_en = 0;
data_count_rst = 0;
ptr_count_rst = 0;
ptr_count_en = 0;
data_load = 0;
data_store = 0;
ocx_out.sop = 0;
ocx_out.eop = 0;
ocx_out.valid = 0;
ocx_out.error = 0;
if(valid)
begin
data_store = 1;
ptr_count_en = 1;
end
case(cur_state)
IDLE:
begin
data_count_rst = 1;
if(i< ptr_count || i==0)
begin
if(ptr_count != 0)
next_state = TX;
else
next_state = IDLE;
end
else
begin
ptr_count_rst = 1;
next_state = IDLE;
i = 0;
end
end
TX:
begin
if(data_count <= temp_ptr[i])
begin
data_count_en = 1;
data_load = 1;
next_state = TX;
ocx_out.valid = temp_valid[i];
if(data_count == 0)
ocx_out.sop = 1;
if(data_count == temp_ptr[i])
begin
ocx_out.eop = 1;
ocx_out.error = temp_error[i];
end
end
else
begin
next_state = IDLE;
i++;
end
end
endcase
end
// data counter
always_ff @ (posedge clk or negedge rst_n)
begin
if(!rst_n || data_count_rst)
begin
data_count <=0;
end
else
begin
data_count <= data_count;
if(data_count_en)
data_count <= data_count+1;
end
end
//ptr_counter
always_ff @ (posedge clk or negedge rst_n)
begin
if(!rst_n || ptr_count_rst)
begin
ptr_count <=0;
end
else
begin
ptr_count <= ptr_count;
if(ptr_count_en)
ptr_count <= ptr_count+1;
end
end
// data register
always_ff @(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
buffer <= '{256{0}};
temp_error <= '{256{0}};
temp_valid <= '{256{0}};
temp_ptr <= '{256{0}};
end
else if(data_store)
begin
temp_error[ptr_count] <= error;
temp_valid[ptr_count] <= valid;
temp_ptr[ptr_count] <= eop_ptr_6;
buffer[ptr_count] <= data_in_512;
end
end
always_comb
begin
ocx_out.data_8 <= 0;
if(data_load && data_count<=temp_ptr[i])
ocx_out.data_8 <= buffer[i] >> (8*data_count);
end
endmodule
Code:
//TOP MODULE
//
//
//`include "ocx_pkg.sv"
//`include "ocx_tx1.sv"
//`include "ocx_rx.sv"
module ocx_top (
input port ocx_in,
input rst_n, clk,
output port ocx_out
);
logic valid, error;
logic [511:0]data_512;
logic [5:0]eop_ptr_6;
ocx_rx rx(ocx_in, rst_n, clk, valid, error, data_512, eop_ptr_6);
ocx_tx tx(rst_n, clk, valid, error, data_512, eop_ptr_6, ocx_out);
endmodule
Code:
// THIS IS PACKAGE.SV
//
//
`ifndef DEFS_DONE // if the already-compiled flag is not set...
`define DEFS_DONE // set the flag
package definitions;
/*
ER -- error
ER_IN -- error because of input error pin
ER_SOP -- error because of SOP with out VALID
ER_EOP -- error because of SOP with out VALID
ER_LL -- error if packet length is less than 2
ER_GT -- error if packet length is greater than 64
ER_CYCLE -- error if number of clkcycles per packet is greater than 128
ER_GAP -- error if gap between the packet is less than 1
ER_ER -- error if error goes high without EOP & VALID*/
typedef enum {ER_IN, ER_SOP, ER_EOP, ER_LL, ER_GT, ER_CYCLE, ER_GAP, ER_ER} ER;
typedef struct {
logic sop,valid,eop,error;
logic [7:0]data_8;
} port;
endpackage
import definitions::*; // import package into $unit
`endif