0% found this document useful (0 votes)
40 views55 pages

Document From ?

The document describes the RTL code and testbench for a finite state machine (FSM) controller. The FSM controller handles the states for writing data to multiple FIFOs, including decoding the address, loading data and parity, handling full FIFO states, and checking for parity errors. It uses the states DECODE_ADDRESS, LOAD_FIRST_DATA, WAIT_TILL_EMPTY, LOAD_DATA, FIFO_FULL_STATE, LOAD_AFTER_FULL, LOAD_PARITY and CHECK_PARITY_ERROR to control the writing process. The testbench applies resets and toggles inputs like FIFO full/empty signals to simulate the controller functionality.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
40 views55 pages

Document From ?

The document describes the RTL code and testbench for a finite state machine (FSM) controller. The FSM controller handles the states for writing data to multiple FIFOs, including decoding the address, loading data and parity, handling full FIFO states, and checking for parity errors. It uses the states DECODE_ADDRESS, LOAD_FIRST_DATA, WAIT_TILL_EMPTY, LOAD_DATA, FIFO_FULL_STATE, LOAD_AFTER_FULL, LOAD_PARITY and CHECK_PARITY_ERROR to control the writing process. The testbench applies resets and toggles inputs like FIFO full/empty signals to simulate the controller functionality.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 55

ROUTER 1X3 PROJECT

Sub Blocks
FIFO
RTL Code
module router_fifo(clk,rstn,soft_rst,lfd_state,we,re,din,dout,full,empty);
parameter width=9,depth=16,add=5;
input clk,rstn,soft_rst,lfd_state,we,re;
input [width-2:0]din;
output reg [width-2:0]dout;
output full,empty;
reg lfd_state_s;
reg [add-1:0]wr_ptr,rd_ptr;
reg[width-1:0]mem[depth-1:0];
reg [6:0]fifo_counter;
integer i,j;
always @(posedge clk)
begin
if(!rstn)
lfd_state_s<=0;
else
lfd_state_s<=lfd_state;
end
always @(posedge clk)
begin
if(!rstn)
begin
for(i=0;i<16;i=i+1)
mem[i]<=0;
end
else if(soft_rst)
begin
for(j=0;j<16;j=j+1)
mem[j]<=0;
end
else
begin
if(we && !full)
mem[wr_ptr[3:0]]<={lfd_state_s,din};
else
mem[wr_ptr[3:0]]<=mem[wr_ptr[3:0]];
end
end
always @(posedge clk)
begin
if(!rstn)
fifo_counter<=0;
else if(soft_rst)
fifo_counter<=0;
else if(re && !empty)
begin
if(mem[rd_ptr[3:0]][8]==1'b1)
fifo_counter<=mem[rd_ptr[3:0]][7:2]+1'b1;
else if(fifo_counter!=0)
fifo_counter<=fifo_counter-1'b1;
end
end
always @(posedge clk)
begin
if(!rstn)
dout<=8'b0;
else if(soft_rst)
dout<=8'bz;
else if(fifo_counter==0 && dout!=0)
dout<=8'bz;
else if(re && !empty)
dout<=mem[rd_ptr[3:0]];
end
always @(posedge clk)
begin
if(!rstn)
begin
wr_ptr<=5'b0;
rd_ptr<=5'b0;
end
else if(soft_rst)
begin
wr_ptr<=5'b0;
rd_ptr<=5'b0;
end
else
begin
if(we && !full)
wr_ptr<=wr_ptr+1'b1;
else
wr_ptr<=wr_ptr;
if(re && !empty)
rd_ptr<=rd_ptr+1'b1;
else
rd_ptr<=rd_ptr;
end
end
assign full=(wr_ptr=={~rd_ptr[4],rd_ptr[3:0]})?1'b1:1'b0;
assign empty=(wr_ptr==rd_ptr)?1'b1:1'b0;
endmodule

TB
module router_fifo_tb();
parameter width=9,depth=16,add=5;
reg clk,rstn,soft_rst,lfd_state,we,re;
reg [width-2:0]din;
wire [width-2:0]dout;
wire full,empty;
reg[width-1:0]mem[depth-1:0];
reg [6:0]fifo_counter;
integer a;
router_fifo dut(clk,rstn,soft_rst,lfd_state,we,re,din,dout,full,empty);
initial
begin
clk=1'b0;
forever
#10 clk=~clk;
end
task initialize;
begin
{rstn,soft_rst,lfd_state,we,re}=5'b01000;
din=8'b0;
end
endtask
task reset;
begin
@(negedge clk)
rstn=0;
@(negedge clk)
rstn=1;
end
endtask
task soft;
begin
@(negedge clk)
soft_rst=1;
@(negedge clk)
soft_rst=0;
end
endtask
task write;
reg [7:0]header,payload_data,parity;
reg [1:0]addr;
reg [5:0]payload_len;
begin
@(negedge clk)
payload_len=6'd12;
addr=2'b10;
we=1'b1;
lfd_state=1'b1;
header={payload_len,addr};
din=header;
for(a=0;a<payload_len;a=a+1)
begin
@(negedge clk)
payload_data=8'b10001100;
lfd_state=1'b0;
din=payload_data;
end
@(negedge clk)
lfd_state=1'b0;
parity=8'b10101111;
din=parity;
end
endtask
task read;
begin
@(negedge clk)
re=1'b1;
we=1'b0;
end
endtask
initial
begin
initialize;
reset;
soft;
write;
#100;
read;
#1000;
$finish();
end
initial
$monitor("clk=%b rstn=%b soft_rst=%b we=%b re=%b lfd_state=%b din=%b dout=%b
full=%b empty=%b",clk,rstn,soft_rst,we,re,lfd_state,din,dout,full,empty);
endmodule

Simulation

Synthesis
SYNCHRONIZER
RTL Code
module router_syn(clk,rstn,detect_add,din,wr_en_reg,rd_en_0,rd_en_1,rd_en_2,full_0,full_1,
full_2,empty_0,empty_1,empty_2,wr_en,fifo_full,valid_out_0,valid_out_1,valid_out_2,soft_rst_
0,soft_rst_1,soft_rst_2);
input clk,rstn,detect_add,wr_en_reg,rd_en_0,rd_en_1,rd_en_2,full_0,full_1,full_2,
empty_0, empty_1,empty_2;
input [1:0]din;
output reg fifo_full;
output reg [2:0]wr_en;
output valid_out_0,valid_out_1,valid_out_2;
output reg soft_rst_0,soft_rst_1,soft_rst_2;
reg [1:0]int_add;
reg [4:0] timer_0,timer_1,timer_2;
always @(posedge clk)
begin
if(!rstn)
int_add<=0;
else if(detect_add)
int_add<=din;
else
int_add<=int_add;
end
always@(wr_en_reg or int_add)
begin
if(wr_en_reg)
begin
case(int_add)
2'b00:wr_en=3'b001;
2'b01:wr_en=3'b010;
2'b10:wr_en=3'b100;
default:wr_en=3'b000;
endcase
end
else
wr_en=3'b0;
end
always @(*)
begin
case(int_add)
2'b00:fifo_full=full_0;
2'b01:fifo_full=full_1;
2'b10:fifo_full=full_2;
default:fifo_full=0;
endcase
end
assign valid_out_0=~empty_0;
assign valid_out_1=~empty_1;
assign valid_out_2=~empty_2;
always@(posedge clk)
begin
if(!rstn)begin
timer_0<=0;
soft_rst_0<=0;end
else if(valid_out_0)
begin
if(!rd_en_0)
begin
if(timer_0==5'd29)begin
soft_rst_0<=1'b1;
timer_0<=0;end
else
begin
soft_rst_0<=0;
timer_0<=timer_0+1'b1;
end
end
end
end
always@(posedge clk)
begin
if(!rstn)begin
timer_1<=0;
soft_rst_1<=0;end
else if(valid_out_1)
begin
if(!rd_en_1)
begin
if(timer_1==5'd29)begin
soft_rst_1<=1'b1;
timer_1<=0;
end
else
begin
soft_rst_1<=0;
timer_1<=timer_1+1'b1;
end
end
end
end
always@(posedge clk)
begin
if(!rstn)begin
timer_2<=0;
soft_rst_2<=0;end
else if(valid_out_2)
begin
if(!rd_en_2)
begin
if(timer_2==5'd29)begin
soft_rst_2<=1'b1;
timer_2<=0;end
else
begin
soft_rst_2<=0;
timer_2<=timer_2+1'b1;
end
end
end
end
endmodule

TB
module router_syn_tb();
reg clk,rstn,detect_add,wr_en_reg,rd_en_0,rd_en_1,rd_en_2,full_0,full_1,full_2,empty_0,
empty_1,empty_2;
reg [1:0]din;
wire fifo_full;
wire [2:0]wr_en;
wire valid_out_0,valid_out_1,valid_out_2;
wire soft_rst_0,soft_rst_1,soft_rst_2;
router_syn dut(clk,rstn,detect_add,din,wr_en_reg,rd_en_0,rd_en_1,rd_en_2,full_0,full_1,full_2,
empty_0,empty_1,empty_2,wr_en,fifo_full,valid_out_0,valid_out_1,valid_out_2,soft_rst_0,
soft_rst_1,soft_rst_2);
initial
begin
clk=1'b0;
forever
#10 clk=~clk;
end
task initialize;
begin
detect_add=1'b0;
wr_en_reg=1'b0;
rd_en_0=0; rd_en_1=0; rd_en_2=0;
full_0=0; full_1=0; full_2=0;
empty_0=1; empty_1=1; empty_2=1;
din=2'b00;
end
endtask
task reset;
begin
@(negedge clk)
rstn=1'b0;
@(negedge clk)
rstn=1'b1;
end
endtask
task detect(input [1:0]w);
begin
@(negedge clk)
detect_add=1'b1;
din=w;
@(negedge clk)
detect_add=1'b0;
end
endtask
task write_en;
begin
@(negedge clk)
wr_en_reg=1'b1;
@(negedge clk)
wr_en_reg=1'b0;
end
endtask
task inputs;
begin
@(negedge clk)
{full_0,full_1,full_2}=3'b111;
@(negedge clk)
{empty_0,empty_1,empty_2}=3'b000;
@(negedge clk)
{rd_en_0,rd_en_1,rd_en_2}=3'b000;
end
endtask
task inputs1;
begin
@(negedge clk)
{full_0,full_1,full_2}=3'b111;
@(negedge clk)
{empty_0,empty_1,empty_2}=3'b000;
@(negedge clk)
{rd_en_0,rd_en_1,rd_en_2}=3'b000;
end
endtask
initial
begin
initialize;
reset;
detect(2'b10);
write_en;
inputs;
#1000;
detect(2'b01);
write_en;
inputs1;
#2000;
$finish();
end
initial
$monitor("clk=%b rstn=%b detect_add=%b wr_en_reg=%b din=%b wr_en=%b fifo_full=%b
rd_en_0=%b rd_en_1=%b rd_en_2=%b v1=%b v2=%b v3=%b soft_rst_0=%b soft_rst_1=%b
soft_rst_2=%b",clk,rstn,detect_add,wr_en_reg,din,wr_en,fifo_full,rd_en_0,rd_en_1,rd_en_2,vali
d_out_0,valid_out_1,valid_out_2,soft_rst_0,soft_rst_1,soft_rst_2);
endmodule

Simulation

Synthesis
CONTROLLER(FSM)
RTL Code
module
fsm(clk,rstn,pkt_valid,parity_done,soft_rst_0,soft_rst_1,soft_rst_2,fifo_full,low_pkt_valid,fifo_e
mpty_0,fifo_empty_1,fifo_empty_2,din,busy,detect_add,ld_state,laf_state,full_state,wr_en_reg,r
st_int_reg,lfd_state);
input clk,rstn,pkt_valid,parity_done,soft_rst_0,soft_rst_1,soft_rst_2,fifo_full,low_pkt_valid,
fifo_empty_0,fifo_empty_1,fifo_empty_2;
input [1:0]din;
output busy,detect_add,ld_state,laf_state,full_state,wr_en_reg,rst_int_reg,lfd_state;
parameter DECODE_ADDRESS=3'b000,
LOAD_FIRST_DATA=3'b001,
WAIT_TILL_EMPTY=3'b010,
LOAD_DATA=3'b011,
FIFO_FULL_STATE=3'b100,
LOAD_AFTER_FULL=3'b101,
LOAD_PARITY=3'b110,
CHECK_PARITY_ERROR=3'b111;
reg [2:0]presentstate,nextstate;
reg [1:0]var_add;
always @(posedge clk)
begin
if(!rstn)
presentstate<=DECODE_ADDRESS;
else if((soft_rst_0&&din==2'b00)||(soft_rst_1&&din==2'b01)||(soft_rst_2&&din==2'b10))
presentstate<=DECODE_ADDRESS;
else
presentstate<=nextstate;
end
always@(posedge clk)
begin
if(!rstn)
var_add<=0;
else if((soft_rst_0&&din==2'b00)||(soft_rst_1&&din==2'b01)||(soft_rst_2&&din==2'b10))
var_add<=0;
else if(DECODE_ADDRESS)
var_add<=din;
else
var_add<=0;
end
always @(*)
begin
case(presentstate)
DECODE_ADDRESS:if((pkt_valid && (din==2'b00) && fifo_empty_0)||(pkt_valid &&
(din==2'b01) && fifo_empty_1)||(pkt_valid && (din==2'b10) && fifo_empty_2))
nextstate<=LOAD_FIRST_DATA;
else if ((pkt_valid && (din==2'b00) && !fifo_empty_0)||(pkt_valid && (din==2'b01) &&
!fifo_empty_1)||(pkt_valid && (din==2'b10) && !fifo_empty_2))
nextstate<=WAIT_TILL_EMPTY;
else
nextstate<=DECODE_ADDRESS;
WAIT_TILL_EMPTY:if((fifo_empty_0 && var_add==2'b00)||(fifo_empty_1 &&
var_add==2'b01)||(fifo_empty_2 && var_add==2'b10))
nextstate<=LOAD_FIRST_DATA;
else
nextstate<=WAIT_TILL_EMPTY;
LOAD_FIRST_DATA:nextstate<=LOAD_DATA;
LOAD_DATA:if(fifo_full)
nextstate<=FIFO_FULL_STATE;
else if(!fifo_full && !pkt_valid)
nextstate<=LOAD_PARITY;
else
nextstate<=LOAD_DATA;
LOAD_PARITY:nextstate<=CHECK_PARITY_ERROR;
CHECK_PARITY_ERROR:if(!fifo_full)
nextstate<=DECODE_ADDRESS;
else
nextstate<=FIFO_FULL_STATE;
FIFO_FULL_STATE:if(!fifo_full)
nextstate<=LOAD_AFTER_FULL;
else
nextstate<=FIFO_FULL_STATE;
LOAD_AFTER_FULL:if(!parity_done && low_pkt_valid)
nextstate<=LOAD_PARITY;
else if(!parity_done && !low_pkt_valid)
nextstate<=LOAD_DATA;
else
nextstate<=DECODE_ADDRESS;
endcase
end
assign detect_add=(presentstate==DECODE_ADDRESS)?1'b1:1'b0;
assign lfd_state=(presentstate==LOAD_FIRST_DATA)?1'b1:1'b0;
assign ld_state=(presentstate==LOAD_DATA)?1'b1:1'b0;
assign laf_state=(presentstate==LOAD_AFTER_FULL)?1'b1:1'b0;
assign rst_int_reg=(presentstate==CHECK_PARITY_ERROR)?1'b1:1'b0;
assign full_state=(presentstate==FIFO_FULL_STATE)?1'b1:1'b0;
assign wr_en_reg=((presentstate==LOAD_DATA) || (presentstate==LOAD_PARITY) ||
(presentstate==LOAD_AFTER_FULL))?1'b1:1'b0;
assign busy=((presentstate==LOAD_FIRST_DATA) ||(presentstate==LOAD_PARITY) ||
(presentstate==FIFO_FULL_STATE) || (presentstate==LOAD_AFTER_FULL) ||
(presentstate==WAIT_TILL_EMPTY) || (presentstate==CHECK_PARITY_ERROR))?1'b1:1'b0;
endmodule

TB
module fsm_tb();
reg clk,rstn,pkt_valid,parity_done,soft_rst_0,soft_rst_1,soft_rst_2,fifo_full,low_pkt_valid,
fifo_empty_0,fifo_empty_1,fifo_empty_2;
reg [1:0]din;
reg [1:0]var_add;
wire busy,detect_add,ld_state,laf_state,full_state,wr_en_reg,rst_int_reg,lfd_state;
fsm dut
(clk,rstn,pkt_valid,parity_done,soft_rst_0,soft_rst_1,soft_rst_2,fifo_full,low_pkt_valid,fifo_empt
y_0,fifo_empty_1,fifo_empty_2,din,busy,detect_add,ld_state,laf_state,full_state,wr_en_reg,rst_i
nt_reg,lfd_state);
initial
begin
clk=1'b0;
forever
#5 clk=~clk;
end
task initialize;
begin
{pkt_valid,parity_done,fifo_full,low_pkt_valid}=4'b0000;
{soft_rst_0,soft_rst_1,soft_rst_2}=3'b0;
{fifo_empty_0,fifo_empty_1,fifo_empty_2}=3'b0;
rstn=1'b1;
end
endtask
task reset;
begin
@(negedge clk)
rstn=1'b0;
@(negedge clk)
rstn=1'b1;
end
endtask
task soft0;
begin
@(negedge clk)
soft_rst_0=1'b1;
@(negedge clk)
soft_rst_0=1'b0;
end
endtask
task soft1;
begin
@(negedge clk)
soft_rst_1=1'b1;
@(negedge clk)
soft_rst_1=1'b0;
end
endtask
task soft2;
begin
@(negedge clk)
soft_rst_2=1'b1;
@(negedge clk)
soft_rst_2=1'b0;
end
endtask
task inputs1;
begin
@(negedge clk)
pkt_valid=1'b1;
din=2'b00;
fifo_empty_0=1'b1;
@(negedge clk)
@(negedge clk)
fifo_full=1'b0;
pkt_valid=1'b0;
@(negedge clk)
@(negedge clk)
fifo_full=1'b0;
end
endtask
task inputs2;
begin
@(negedge clk)
pkt_valid=1'b1;
din=2'b01;
fifo_empty_1=1'b1;
@(negedge clk)
@(negedge clk)
fifo_full=1'b1;
@(negedge clk)
fifo_full=1'b0;
@(negedge clk)
parity_done=1'b1;
end
endtask
task inputs3;
begin
@(negedge clk)
pkt_valid=1'b1;
din=2'b10;
fifo_empty_2=1'b1;
@(negedge clk)
@(negedge clk)
fifo_full=1'b0;
pkt_valid=1'b0;
@(negedge clk)
@(negedge clk)
fifo_full=1'b1;
@(negedge clk)
fifo_full=1'b0;
@(negedge clk)
parity_done=1'b0;
low_pkt_valid=1'b0;
@(negedge clk)
fifo_full=1'b1;
@(negedge clk)
fifo_full=1'b0;
@(negedge clk)
parity_done=1'b0;
low_pkt_valid=1'b1;
@(negedge clk)
@(negedge clk)
fifo_full=1'b1;
@(negedge clk)
fifo_full=1'b0;
@(negedge clk)
parity_done=1'b1;
end
endtask
initial
begin
reset;
initialize;
soft0;
inputs1;
#20;
soft1;
inputs2;
#20;
soft2;
inputs3;
#500;
$finish;
end
initial
$monitor("clk=%b rstn=%b pkt=%b pd=%b sr0=%b sr1=%b sr2=%b ff=%b lpkt=%b fe0=%b
fe1=%b fe2=%b din=%b b=%b da=%b ld=%b laf=%b fs=%b wer=%b rir=%b
lfd=%b",clk,rstn,pkt_valid,parity_done,soft_rst_0,soft_rst_1,soft_rst_2,fifo_full,low_pkt_valid,fi
fo_empty_0,fifo_empty_1,fifo_empty_2,din,busy,detect_add,ld_state,laf_state,full_state,wr_en_r
eg,rst_int_reg,lfd_state);
endmodule

Simulation

Synthesis
REGISTER
RTL Code
Module router_reg(clk,rstn,pkt_valid,din,fifo_full,rst_int_reg,detect_add,ld_state,laf_state,
full_state,lfd_state,parity_done,low_pkt_valid,err,dout);
input clk,rstn,pkt_valid,fifo_full,rst_int_reg,detect_add,ld_state,laf_state,full_state,lfd_state;
input [7:0]din;
output reg [7:0]dout;
output reg parity_done,low_pkt_valid,err;
reg [7:0] header_byte,fifo_full_state_byte,internal_parity,packet_parity;
always @(posedge clk)
begin
if(!rstn)
dout<=0;
else
begin
if(lfd_state)
dout<=header_byte;
else if(ld_state && !fifo_full)
dout<=din;
else if(laf_state)
dout<=fifo_full_state_byte;
else
dout<=dout;
end
end
always @(posedge clk)
begin
if(!rstn)
begin
header_byte<=0;
fifo_full_state_byte<=0;
end
else
begin
if(detect_add && pkt_valid)
header_byte<=din;
else if(ld_state && fifo_full)
fifo_full_state_byte<=din;
end
end
always @(posedge clk)
begin
if(!rstn)
parity_done<=0;
else
begin
if(ld_state && !fifo_full && !pkt_valid)
parity_done<=1'b1;
else if (laf_state && low_pkt_valid && !parity_done)
parity_done<=1'b1;
else if(detect_add)
parity_done<=1'b0;
end
end
always @(posedge clk)
begin
if(!rstn)
low_pkt_valid<=1'b0;
else
begin
if(ld_state && !pkt_valid)
low_pkt_valid<=1'b1;
else if(rst_int_reg)
low_pkt_valid<=1'b0;
end
end
always @(posedge clk)
begin
if(!rstn)
packet_parity<=0;
else if((ld_state && !fifo_full && !pkt_valid) || (laf_state &&!parity_done && low_pkt_valid))
packet_parity<=din;
else if(!pkt_valid && rst_int_reg)
packet_parity<=0;
else if(detect_add)
packet_parity<=0;
end
always @(posedge clk)
begin
if(!rstn)
internal_parity<=0;
else if(detect_add)
internal_parity<=0;
else if(lfd_state)
internal_parity<=header_byte;
else if(ld_state && !full_state && pkt_valid)
internal_parity<=internal_parity^din;
else if(!pkt_valid && rst_int_reg)
internal_parity<=0;
end
always @(posedge clk)
begin
if(!rstn)
err<=0;
else
begin
if(parity_done==1'b1 && (packet_parity !=internal_parity))
err<=1'b1;
else
err<=1'b0;
end
end
endmodule

TB
module router_reg_tb();
reg clk,rstn,pkt_valid,fifo_full,rst_int_reg,detect_add,ld_state,laf_state,full_state,lfd_state;
reg [7:0]din;
wire [7:0]dout;
wire parity_done,low_pkt_valid,err;
integer i;
router_reg
dut(clk,rstn,pkt_valid,din,fifo_full,rst_int_reg,detect_add,ld_state,laf_state,full_state,lfd_state,pa
rity_done,low_pkt_valid,err,dout);
initial
begin
clk=1'b0;
forever
#10 clk=~clk;
end
task initialize;
begin
{rstn,pkt_valid,fifo_full,rst_int_reg,detect_add,ld_state,laf_state,full_state,lfd_state}=9'b0;
din=8'b0;
end
endtask
task reset;
begin
@(negedge clk)
rstn=1'b0;
@(negedge clk)
rstn=1'b1;
end
endtask
task inputs;
reg [7:0] header,payload_data,parity;
reg [5:0]payload_len;
reg [1:0]addr;
begin
@(negedge clk)
payload_len=6'd15;
addr=2'b10;
pkt_valid=1'b1;
detect_add=1'b1;
header={payload_len,addr};
parity=header;
din=header;
@(negedge clk)
detect_add=1'b0;
lfd_state=1'b1;
fifo_full=1'b0;
full_state=1'b0;
laf_state=1'b0;
for(i=0;i<15;i=i+1)
begin
@(negedge clk)
lfd_state=1'b0;
fifo_full=1'b0;
ld_state=1'b1;
laf_state=1'b0;
payload_data={$random}%256;
din=payload_data;
parity=parity^din;
end
wait(payload_len>14)begin
laf_state=1'b1;
fifo_full=1'b1;
full_state=1'b1;end
@(negedge clk)
pkt_valid=1'b0;
din=parity;
@(negedge clk)
ld_state=1'b0;
end
endtask
initial
begin
initialize;
reset;
inputs;
#500;
$finish;
end
endmodule

Simulation

Synthesis
ROUTER-TOP
RTL Code
modulerouter_top(clk,rstn,rd_en_0,rd_en_1,rd_en_2,din,pkt_valid,dout_0,dout_1,dout_2,
valid_out_0,valid_out_1,valid_out_2,err,busy);
input clk,rstn,rd_en_0,rd_en_1,rd_en_2,pkt_valid;
input [7:0]din;
output [7:0] dout_0,dout_1,dout_2;
output valid_out_0,valid_out_1,valid_out_2,err,busy;
wire [7:0] dout;
wire parity_done,soft_rst_0,soft_rst_1,soft_rst_2,fifo_full,low_pkt_valid,empty_0,empty_1,
empty_2,detect_add,ld_state,laf_state,full_state,wr_en_reg,rst_int_reg,lfd_state,full_0,full_1,
full_2;
wire [2:0]wr_en;

router_fifo f0(clk,rstn,soft_rst_0,lfd_state,wr_en[0],rd_en_0,dout,dout_0,full_0,empty_0);
router_fifo f1(clk,rstn,soft_rst_1,lfd_state,wr_en[1],rd_en_1,dout,dout_1,full_1,empty_1);
router_fifo f2(clk,rstn,soft_rst_2,lfd_state,wr_en[2],rd_en_2,dout,dout_2,full_2,empty_2);

router_syn s(clk,rstn,detect_add,din[1:0],wr_en_reg,rd_en_0,rd_en_1,rd_en_2,full_0,full_1,
full_2,empty_0,empty_1,empty_2,wr_en,fifo_full,valid_out_0,valid_out_1,valid_out_2,soft_rst_
0,soft_rst_1,soft_rst_2);

fsm f(clk,rstn,pkt_valid,parity_done,soft_rst_0,soft_rst_1,soft_rst_2,fifo_full,low_pkt_valid,
empty_0,empty_1,empty_2,din[1:0],busy,detect_add,ld_state,laf_state,full_state,wr_en_reg,rst_i
nt_reg,lfd_state);

router_reg r(clk,rstn,pkt_valid,din,fifo_full,rst_int_reg,detect_add,ld_state,laf_state,full_state,
lfd_state,parity_done,low_pkt_valid,err,dout);
endmodule

TB
module router_top_tb();
reg clk,rstn,rd_en_0,rd_en_1,rd_en_2,pkt_valid;
reg [7:0]din;
wire [7:0]dout_0,dout_1,dout_2;
wire valid_out_0,valid_out_1,valid_out_2,err,busy;
integer i;
router_top
dut(clk,rstn,rd_en_0,rd_en_1,rd_en_2,din,pkt_valid,dout_0,dout_1,dout_2,valid_out_0,valid_out
_1,valid_out_2,err,busy);
initial
begin
clk=1'b0;
forever
#10 clk=~clk;
end
task initialize;
begin
{rstn,rd_en_0,rd_en_1,rd_en_2,pkt_valid}=5'b0;
din=8'b0;
end
endtask
task reset;
begin
@(negedge clk)
rstn=1'b0;
@(negedge clk)
rstn=1'b1;
end
endtask
task packet;
reg [7:0]header,payload_data,parity;
reg [5:0]payload_len;
reg [1:0]addr;
begin
wait(!busy)begin
@(negedge clk)
payload_len=6'd12;
addr=2'b01;
pkt_valid=1'b1;
header={payload_len,addr};
parity=8'b0;
din=header;
parity=parity^header;end

@(negedge clk)
for(i=0;i<payload_len;i=i+1)
begin
wait(!busy)
@(negedge clk)
payload_data={$random}%256;
din=payload_data;
parity=parity^din;
end
wait(!busy)
@(negedge clk)
pkt_valid=0;
din=parity;
end
endtask
task packet1;
reg [7:0]header,payload_data,parity;
reg [5:0]payload_len;
reg [1:0]addr;
begin
wait(!busy)begin
@(negedge clk)
payload_len=6'd14;
addr=2'b10;
pkt_valid=1'b1;
header={payload_len,addr};
parity=8'b0;
din=header;
parity=parity^header;end

@(negedge clk)
for(i=0;i<payload_len;i=i+1)
begin
wait(!busy)
@(negedge clk)
payload_data={$random}%256;
din=payload_data;
parity=parity^din;
end
wait(!busy)
@(negedge clk)
pkt_valid=0;
din=parity;
end
endtask
task packet2;
reg [7:0]header,payload_data,parity;
reg [5:0]payload_len;
reg [1:0]addr;
begin
wait(!busy)begin
@(negedge clk)
payload_len=6'd16;
addr=2'b00;
pkt_valid=1'b1;
header={payload_len,addr};
parity=8'b0;
din=header;
parity=parity^header;end

@(negedge clk)
for(i=0;i<payload_len;i=i+1)
begin
wait(!busy)
@(negedge clk)
payload_data={$random}%256;
din=payload_data;
parity=parity^din;
end
wait(!busy)
@(negedge clk)
pkt_valid=0;
din=parity;
end
endtask

initial
begin
initialize;
reset;
packet;
@(negedge clk)
@(negedge clk)
rd_en_1=1'b1;
packet1;
@(negedge clk)
@(negedge clk)
rd_en_2=1'b1;
fork
packet2;
begin
@(negedge clk)
@(negedge clk)
rd_en_0=1'b1;
end
join
#800 $finish();
end
endmodule

Simulation

Synthesis
ROUTER1X3 LINTING

Warnings
FIFO
RTL Code
module router_fifo(clk,rstn,soft_rst,lfd_state,we,re,din,dout,full,empty);
parameter width=9,depth=16,add=5;
input clk,rstn,soft_rst,lfd_state,we,re;
input [width-2:0]din;
output reg [width-2:0]dout;
output full,empty;
reg lfd_state_s;
reg [add-1:0]wr_ptr,rd_ptr;
reg[width-1:0]mem[depth-1:0];
reg [6:0]fifo_counter;
integer i,j;
always @(posedge clk)
begin
if(!rstn)
lfd_state_s<=0;
else
lfd_state_s<=lfd_state;
end
always @(posedge clk)
begin
if(!rstn)
begin
for(i=0;i<16;i=i+1)
mem[i]<=0;
end
else if(soft_rst)
begin
for(j=0;j<16;j=j+1)
mem[j]<=0;
end
else
begin
if(we && !full)
mem[wr_ptr[3:0]]<={lfd_state_s,din};
else
mem[wr_ptr[3:0]]<=mem[wr_ptr[3:0]];
end
end
always @(posedge clk)
begin
if(!rstn)
fifo_counter<=0;
else if(soft_rst)
fifo_counter<=0;
else if(re && !empty)
begin
if(mem[rd_ptr[3:0]][8]==1'b1)
fifo_counter<=mem[rd_ptr[3:0]][7:2]+1'b1;
else if(fifo_counter!=0)
fifo_counter<=fifo_counter-1'b1;
end
end
wire w1=(fifo_counter==0 && dout!=0)?1'b1:1'b0;
always @(posedge clk)
begin
if(!rstn)
dout<=8'b0;
else if(soft_rst)
dout<=8'bz;
else if(w1)
dout<=8'bz;
else if(re && !empty)
dout<=mem[rd_ptr[3:0]];
end
always @(posedge clk)
begin
if(!rstn)
begin
wr_ptr<=5'b0;
rd_ptr<=5'b0;
end
else if(soft_rst)
begin
wr_ptr<=5'b0;
rd_ptr<=5'b0;
end
else
begin
if(we && !full)
wr_ptr<=wr_ptr+1'b1;
else
wr_ptr<=wr_ptr;
if(re && !empty)
rd_ptr<=rd_ptr+1'b1;
else
rd_ptr<=rd_ptr;
end
end
assign full=(wr_ptr=={~rd_ptr[4],rd_ptr[3:0]})?1'b1:1'b0;
assign empty=(wr_ptr==rd_ptr)?1'b1:1'b0;
endmodule

SYNCHRONIZER
RTL Code
module router_syn(clk,rstn,detect_add,din,wr_en_reg,rd_en_0,rd_en_1,rd_en_2,full_0,full_1,
full_2,empty_0,empty_1,empty_2,wr_en,fifo_full,valid_out_0,valid_out_1,valid_out_2,soft_rst_
0,soft_rst_1,soft_rst_2);
input clk,rstn,detect_add,wr_en_reg,rd_en_0,rd_en_1,rd_en_2,full_0,full_1,full_2,
empty_0, empty_1,empty_2;
input [1:0]din;
output reg fifo_full;
output reg [2:0]wr_en;
output valid_out_0,valid_out_1,valid_out_2;
output reg soft_rst_0,soft_rst_1,soft_rst_2;
reg [1:0]int_add;
reg [4:0] timer_0,timer_1,timer_2;
always @(posedge clk)
begin
if(!rstn)
int_add<=0;
else if(detect_add)
int_add<=din;
else
int_add<=int_add;
end
always@(wr_en_reg or int_add)
begin
if(wr_en_reg)
begin
case(int_add)
2'b00:wr_en=3'b001;
2'b01:wr_en=3'b010;
2'b10:wr_en=3'b100;
default:wr_en=3'b000;
endcase
end
else
wr_en=3'b0;
end
always @(*)
begin
case(int_add)
2'b00:fifo_full=full_0;
2'b01:fifo_full=full_1;
2'b10:fifo_full=full_2;
default:fifo_full=0;
endcase
end
assign valid_out_0=~empty_0;
assign valid_out_1=~empty_1;
assign valid_out_2=~empty_2;
wire w0=(timer_0==5'd29)?1'b1:1'b0;
wire w1=(timer_1==5'd29)?1'b1:1'b0;
wire w2=(timer_2==5'd29)?1'b1:1'b0;
always@(posedge clk)
begin
if(!rstn)begin
timer_0<=0;
soft_rst_0<=0;end
else if(valid_out_0)
begin
if(!rd_en_0)
begin
if(w0)begin
soft_rst_0<=1'b1;
timer_0<=0;end
else
begin
soft_rst_0<=0;
timer_0<=timer_0+1'b1;
end
end
end
end
always@(posedge clk)
begin
if(!rstn)begin
timer_1<=0;
soft_rst_1<=0;end
else if(valid_out_1)
begin
if(!rd_en_1)
begin
if(w1)begin
soft_rst_1<=1'b1;
timer_1<=0;
end
else
begin
soft_rst_1<=0;
timer_1<=timer_1+1'b1;
end
end
end
end
always@(posedge clk)
begin
if(!rstn)begin
timer_2<=0;
soft_rst_2<=0;end
else if(valid_out_2)
begin
if(!rd_en_2)
begin
if(w2)begin
soft_rst_2<=1'b1;
timer_2<=0;end
else
begin
soft_rst_2<=0;
timer_2<=timer_2+1'b1;
end
end
end
end
endmodule
RISC V LINTING

You might also like