Document From ?
Document From ?
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