Professional Documents
Culture Documents
BhagyasreeKV BRN46 RouterProject
BhagyasreeKV BRN46 RouterProject
BhagyasreeKV BRN46 RouterProject
FIFO
1.1 RTL -FIFO
module router_fifo (clock, resetn, write_enb, read_enb, lfd_state,soft_reset,data_in,full,
empty,data_out);
input clock, resetn, write_enb, read_enb, lfd_state, soft_reset;
input [7:0]data_in;
output full, empty;
output reg [7:0]data_out;
parameter DEPTH=16;
parameter WIDTH=9;
reg [8:0]mem[15:0];
reg [6:0]counter;
reg [4:0]rdptr;
reg [4:0]wrptr;
reg lfd_temp;
integer i,j;
always@(posedge clock)
begin
if(~resetn)
lfd_temp<=1'b0;
else
lfd_temp<=lfd_state;
end
wrptr<=0;
end
else if(soft_reset)
begin
for(j=0;j<16;j=j+1)
mem[j]<=0;
data_out<=8'dz;
wrptr<=0;
end
else if( write_enb && (!full))
begin
{mem[wrptr[3:0]][8],mem[wrptr[3:0]][7:0]}<={lfd_temp,data_in};
wrptr<=wrptr+1;
end
end
endmodule
reg[4:0]wrptr,rdptr;
reg[6:0]counter;
integer k;
initial
begin
clock=0;
forever #5 clock=~clock;
end
task initialize;
begin
{write_enb,soft_reset,read_enb,data_in,lfd_state,counter}=0;
wrptr=0;
rdptr=0;
end
endtask
task Resetn;
begin
@(negedge clock)
resetn=1'b0;
@(negedge clock)
resetn=1'b1;
end
endtask
task Soft_Reset;
begin
@(negedge clock)
soft_reset=1'b1;
@(negedge clock)
soft_reset=1'b0;
end
endtask
task write;
reg[7:0]payload_data,parity,header;
reg[5:0]payload_len;
reg[1:0]addr;
begin
@(negedge clock);
payload_len=6'd14;
addr=2'b01;
header={payload_len,addr};
data_in=header;
lfd_state=1'b1;
write_enb=1;
for(k=0;k<payload_len;k=k+1)
begin
@(negedge clock)
lfd_state=0;
payload_data={$random}%256;
data_in=payload_data;
end
@(negedge clock)
parity={$random}%256;
data_in=parity;
end
endtask
initial
begin
initialize;
Resetn;
Soft_Reset;
write;
read(0,1);
#200 $finish;
end
initial
$monitor("clock=%b,resetn=%b,write_enb=%b,read_enb=%b,data_in=%b,lfd_state=%b,empty=%b,f
ull=%b,data_out=%b",clock,resetn,write_enb,read_enb,data_in,lfd_state,empty,full,data_out);
endmodule
2.Synchronizer
reg[1:0]temp;
reg[4:0]counter_0,counter_1,counter_2;
always@(posedge clock)
begin
if(!resetn)
temp <= 2'b11;
else if(detect_add)
temp <= data_in;
else
temp <= temp;
end
always@(*)
begin
case(temp)
2'b00: fifo_full<=full_0; // fifo fifo_full logic
2'b01: fifo_full<=full_1;
2'b10: fifo_full<=full_2;
default: fifo_full<=1'b0;
endcase
end
2'b01: write_enb<=3'b010;
2'b10: write_enb<=3'b100;
default: write_enb<=3'b000;
endcase
end
else
write_enb <= 3'b000;
end
always@(posedge clock)
begin
if(!resetn)
{counter_0,counter_1,counter_2} = 0;
else
case(temp)
2'b00: begin
if(vld_out_0 && (!read_enb_0) && (!soft_reset_0))
counter_0<=counter_0 + 1;
else
counter_0<=0;
end
2'b01: begin
if(vld_out_1 && (!read_enb_1) && (!soft_reset_1))
counter_1<=counter_1 + 1;
else
counter_1<=0;
end
2'b10: begin
if(vld_out_2 && (!read_enb_2) && (!soft_reset_2))
counter_2<=counter_2 + 1;
else
counter_2<=0;
end
default: {counter_0,counter_1,counter_2} = 0;
endcase
end
endmodule
2.2Test Bench
module router_sync_tb();
reg
clock,resetn,detect_add,full_0,full_1,full_2,empty_0,empty_1,empty_2,write_enb_reg,read_enb_0,rea
d_enb_1,read_enb_2;
reg [1:0]data_in;
wire fifo_full;
wire vld_out_0,vld_out_1,vld_out_2,soft_reset_0,soft_reset_1,soft_reset_2;
wire [2:0]write_enb;
router_sync
DUT(clock,resetn,data_in,detect_add,full_0,full_1,full_2,empty_0,empty_1,empty_2,write_enb_reg,r
ead_enb_0,read_enb_1,read_enb_2,write_enb,fifo_full,vld_out_0,vld_out_1,vld_out_2,soft_reset_0,s
oft_reset_1,soft_reset_2);
initial
begin
clock=0;
forever
#5 clock=~clock;
end
task Resetn;
begin
@(negedge clock)
resetn=1'b0;
@(negedge clock)
resetn=1'b1;
end
endtask
task write_enb_s; //write_enb_reg
begin
write_enb_reg=1'b1;
@(negedge clock);
//write_enb_reg=1'b0;
end
endtask
task data(input[1:0]m);
begin
data_in=m;
#10;
end
endtask
initial
begin
Resetn;
data(00);
detect_add=1'b1;
read_enb_0=1'b0;
read_enb_1=1'b0;
read_enb_2=1'b1;
write_enb_s;
full_0=1'b1;
full_1=1'b0;
full_2=1'b0;
empty_0=1'b0;
empty_1=1'b1;
empty_2=1'b1;
#300;
#600;
data(01);
detect_add=1'b1;
read_enb_0=1'b0;
read_enb_1=1'b0;
read_enb_2=1'b1;
write_enb_s;
full_0=1'b0;
full_1=1'b1;
full_2=1'b0;
empty_0=1'b1;
empty_1=1'b0;
empty_2=1'b1;
#300;
#600;
data(10);
detect_add=1'b1;
read_enb_0=1'b1;
read_enb_1=1'b0;
read_enb_2=1'b0;
write_enb_s;
full_0=1'b0;
full_1=1'b0;
full_2=1'b1;
empty_0=1'b1;
empty_1=1'b1;
empty_2=1'b0;
#300;
#600;
#1000 $finish;
end
initial
begin
$monitor($time,"clock=%b,resetn=%b,data_in=%b,detect_add=%b,full_0=%b,full_1=%b,full_2=%b,
empty_0=%b,empty_1=%b,empty_2=%b,write_enb_reg=%b,read_enb_0=%b,read_enb_1=%b,read_
enb_2=%b,write_enb=%b,fifo_full=%b,vld_out_0=%b,vld_out_1=%b,vld_out_2=%b,soft_reset_0=
%b,soft_reset_1=%b,soft_reset_2=%b",clock,resetn,data_in,detect_add,full_0,full_1,full_2,empty_0,e
mpty_1,empty_2,write_enb_reg,read_enb_0,read_enb_1,read_enb_2,write_enb,fifo_full,vld_out_0,vl
d_out_1,vld_out_2,soft_reset_0,soft_reset_1,soft_reset_2) ;
end
endmodule
3.FSM
parameter
DECODE_ADDRESS = 3'b000,
LOAD_FIRST_DATA = 3'b001,
LOAD_DATA = 3'b010,
FIFO_FULL_STATE = 3'b011,
LOAD_AFTER_FULL = 3'b100,
LOAD_PARITY = 3'b101,
CHECK_PARITY_ERROR = 3'b110,
WAIT_TILL_EMPTY = 3'b111;
reg [2:0]state,next_state;
reg [1:0]temp;
always@(posedge clock)
begin
if(~resetn)
temp<=2'b0;
else if(detect_add)
temp<=data_in;
end
always@(posedge clock)
begin
if(!resetn)
state<= DECODE_ADDRESS;
else if((soft_reset_0 && (temp==2'b00)) || (soft_reset_1 && (temp==2'b01)) ||
(soft_reset_2 && (temp==2'b10)))
state<= DECODE_ADDRESS;
else
state<= next_state;
end
always@(*)
begin
next_state= DECODE_ADDRESS;
case(state)
DECODE_ADDRESS :
if((pkt_valid && (data_in[1:0]==2'b00)) && fifo_empty_0 || (pkt_valid &&
(data_in[1:0]==2'b01)) && fifo_empty_1 || (pkt_valid && (data_in[1:0]==2'b10)) && fifo_empty_2)
next_state=LOAD_FIRST_DATA;
else if((pkt_valid && (data_in[1:0]==2'b00)) && ~fifo_empty_0 || (pkt_valid
&& (data_in[1:0]==2'b01)) && ~fifo_empty_1 || (pkt_valid && (data_in[1:0]==2'b10)) &&
~fifo_empty_2)
next_state=WAIT_TILL_EMPTY;
else
next_state=DECODE_ADDRESS;
LOAD_FIRST_DATA :
next_state=LOAD_DATA;
LOAD_DATA :
if(fifo_full==1)
next_state=FIFO_FULL_STATE;
else if(fifo_full==0 && pkt_valid==0)
next_state=LOAD_PARITY;
else
next_state=LOAD_DATA;
FIFO_FULL_STATE :
if(fifo_full==0)
next_state=LOAD_AFTER_FULL;
else
next_state=FIFO_FULL_STATE;
LOAD_AFTER_FULL :
if(parity_done==0 && low_packet_valid==1)
next_state=LOAD_PARITY;
else if(parity_done==0 && low_packet_valid==0)
next_state=LOAD_DATA;
else if(parity_done==1)
next_state=DECODE_ADDRESS;
LOAD_PARITY :
next_state=CHECK_PARITY_ERROR;
CHECK_PARITY_ERROR :
if(fifo_full==1)
next_state=FIFO_FULL_STATE;
else
next_state=DECODE_ADDRESS;
WAIT_TILL_EMPTY :
if((fifo_empty_0 && (temp==2'b00)) || (fifo_empty_1 && (temp==2'b01)) ||
(fifo_empty_2 && (temp==2'b10)))
next_state=LOAD_FIRST_DATA;
else
next_state=WAIT_TILL_EMPTY;
default :
next_state=DECODE_ADDRESS;
endcase
end
endmodule
router_fsm
DUT(clock,resetn,pkt_valid,data_in,fifo_full,fifo_empty_0,fifo_empty_1,fifo_empty_2,soft_reset_0,s
oft_reset_1,soft_reset_2,parity_done,low_packet_valid,write_enb_reg,detect_add,ld_state,laf_state,lfd
_state,full_state,rst_int_reg,busy);
initial
begin
clock=0;
forever
#(CYCLE/2) clock=~clock;
end
task Resetn;
begin
@(negedge clock)
resetn=1'b0;
@(negedge clock)
resetn=1'b1;
end
endtask
task initialize;
begin
pkt_valid = 1'b0;
data_in = 2'b00;
fifo_full = 1'b0;
fifo_empty_0 = 1'b0;
fifo_empty_1 = 1'b0;
fifo_empty_2 = 1'b0;
soft_reset_0 = 1'b0;
soft_reset_1 = 1'b0;
soft_reset_2 = 1'b0;
parity_done = 1'b0;
low_packet_valid = 1'b1;
end
endtask
endmodule
module router_reg_tb();
reg clock,resetn,pkt_valid,fifo_full,detect_add,ld_state,laf_state,full_state,lfd_state,rst_int_reg;
reg [7:0] data_in;
wire err,parity_done,low_packet_valid;
wire [7:0] dout;
integer k;
router_reg
DUT(clock,resetn,pkt_valid,data_in,fifo_full,detect_add,ld_state,laf_state,full_state,lfd_state,rst_int_r
eg,err,parity_done,low_packet_valid,dout);
initial
begin
clock=0;
forever
#5 clock=~clock;
end
task initialize;
begin
pkt_valid=1'b0;
data_in=2'b00;
fifo_full=1'b0;
detect_add=1'b0;
ld_state=1'b0;
laf_state=1'b0;w
full_state=1'b0;
lfd_state=1'b0;
rst_int_reg=1'b0;
end
endtask
task Resetn;
begin
@(negedge clock)
resetn=1'b0;
@(negedge clock)
resetn=1'b1;
end
endtask
task goodpkt_gen;
reg[7:0]payload_data,parity,header;
reg[5:0]payload_len;
reg[1:0]addr;
begin
@(negedge clock);
payload_len=6'd14;
addr=2'b01;
parity=8'b00000000;
detect_add=1'b1;
pkt_valid=1'b1;
header={payload_len,addr};
data_in=header;
parity=parity^data_in;
@(negedge clock)
detect_add=1'b0;
lfd_state=1'b1;
for(k=0;k<payload_len;k=k+1)
begin
@(negedge clock)
lfd_state=0;
ld_state=1'b1;
payload_data={$random}%256;
data_in=payload_data;
parity=parity^data_in;
end
@(negedge clock)
pkt_valid=1'b0;
data_in=parity;
@(negedge clock)
ld_state=1'b0;
end
endtask
task badpkt_gen;
reg[7:0]payload_data,parity,header;
reg[5:0]payload_len;
reg[1:0]addr;
begin
@(negedge clock);
payload_len=6'd14;
addr=2'b01;
parity=8'b00000000;
detect_add=1'b1;
pkt_valid=1'b1;
header={payload_len,addr};
data_in=header;
parity=parity^data_in;
@(negedge clock)
detect_add=1'b0;
lfd_state=1'b1;
for(k=0;k<payload_len;k=k+1)
begin
@(negedge clock)
lfd_state=1'b0;
ld_state=1'b1;
payload_data={$random}%256;
data_in=payload_data;
parity=parity^data_in;
end
@(negedge clock)
pkt_valid=1'b0;
data_in=~parity;
@(negedge clock)
ld_state=1'b0;
end
endtask
initial
begin
initialize;
Resetn;
goodpkt_gen;
#170;
badpkt_gen;
#1000 $finish;
end
initial
$monitor("clock=%b,resetn=%b,pkt_valid=%b,data_in=%b,fifo_full=%b,detect_add=%b,ld_state=%
b,laf_state=%b,full_state=%b,lfd_state=%b,rst_int_reg=%b,err=%b,parity_done=%b,low_packet_vali
d=%b,dout=%b,internal_parity=%b,packet_parity_byte=%b",clock,resetn,pkt_valid,data_in,fifo_full,
detect_add,ld_state,laf_state,full_state,lfd_state,rst_int_reg,err,parity_done,low_packet_valid,dout,DU
T.internal_parity,DUT.packet_parity_byte);
endmodule
4.TOP MODULE
wire[2:0] write_enb;
wire[7:0]dout;
router_fsm fsm1(.clock(clock),
.resetn(resetn),
.pkt_valid(pkt_valid),
.data_in(data_in[1:0]),
.fifo_full(fifo_full),
.fifo_empty_0(empty_0),
.fifo_empty_1(empty_1),
.fifo_empty_2(empty_2),
.soft_reset_0(soft_reset_0),
.soft_reset_1(soft_reset_1),
.soft_reset_2(soft_reset_2),
.parity_done(parity_done),
.low_packet_valid(low_packet_valid),
.write_enb_reg(write_enb_reg),
.detect_add(detect_add),
.ld_state(ld_state),
.laf_state(laf_state),
.lfd_state(lfd_state),
.full_state(full_state),
.rst_int_reg(rst_int_reg),
.busy(busy));
router_sync synchronizer(.clock(clock),
.resetn(resetn),
.data_in(data_in[1:0]),
.detect_add(detect_add),
.full_0(full_0),
.full_1(full_1),
.full_2(full_2),
.empty_0(empty_0),
.empty_1(empty_1),
.empty_2(empty_2),
.write_enb_reg(write_enb_reg),
.read_enb_0(read_enb_0),
.read_enb_1(read_enb_1),
.read_enb_2(read_enb_2),
.write_enb(write_enb),
.fifo_full(fifo_full),
.vld_out_0(vld_out_0),
.vld_out_1(vld_out_1),
.vld_out_2(vld_out_2),
.soft_reset_0(soft_reset_0),
.soft_reset_1(soft_reset_1),
.soft_reset_2(soft_reset_2));
router_reg r1(.clock(clock),
.resetn(resetn),
.pkt_valid(pkt_valid),
.data_in(data_in),
.fifo_full(fifo_full),
.detect_add(detect_add),
.ld_state(ld_state),
.laf_state(laf_state),
.full_state(full_state),
.lfd_state(lfd_state),
.rst_int_reg(rst_int_reg),
.err(err),
.parity_done(parity_done),
.low_packet_valid(low_packet_valid),
.dout(dout));
router_fifo fifo_0(.clock(clock),
.resetn(resetn),
.data_in(dout),
.read_enb(read_enb_0),
.write_enb(write_enb[0]),
.lfd_state(lfd_state),
.soft_reset(soft_reset_0),
.data_out(data_out_0),
.full(full_0),
.empty(empty_0));
router_fifo fifo_1(.clock(clock),
.resetn(resetn),
.data_in(dout),
.read_enb(read_enb_1),
.write_enb(write_enb[1]),
.lfd_state(lfd_state),
.soft_reset(soft_reset_1),
.data_out(data_out_1),
.full(full_1),
.empty(empty_1));
router_fifo fifo_2(.clock(clock),
.resetn(resetn),
.data_in(dout),
.read_enb(read_enb_2),
.write_enb(write_enb[2]),
.lfd_state(lfd_state),
.soft_reset(soft_reset_2),
.data_out(data_out_2),
.full(full_2),
.empty(empty_2));
endmodule
integer i;
router_top
DUT(clock,resetn,data_in,pkt_valid,read_enb_0,read_enb_1,read_enb_2,data_out_0,data_out_1,data_
out_2,vld_out_0,vld_out_1,vld_out_2,err,busy);
initial
begin
clock=0;
forever
#5 clock=~clock;
end
task initialize;
begin
data_in=8'd0;
pkt_valid=1'b0;
read_enb_0=1'b0;
read_enb_1=1'b0;
read_enb_2=1'b0;
end
endtask
task Resetn;
begin
@(negedge clock)
resetn=1'b0;
@(negedge clock)
resetn=1'b1;
end
endtask
task pkt_gen_14;
reg[7:0]payload_data,parity,header;
reg[5:0]payload_len;
reg[1:0]addr;
begin
@(negedge clock);
wait(~busy)
@(negedge clock);
payload_len=6'd14;
addr=2'b00; //valid packet
header={payload_len,addr};
parity=8'd0;
data_in=header;
pkt_valid=1'b1;
parity=parity^data_in;
@(negedge clock);
wait(~busy)
for(i=0;i<payload_len;i=i+1)
begin
@(negedge clock);
wait(~busy)
payload_data={$random}%256;
data_in=payload_data;
parity=parity^data_in;
end
@(negedge clock);
wait(~busy)
pkt_valid=1'b0;
data_in=parity;
end
endtask
task pkt_gen_16;
reg[7:0]payload_data,parity,header;
reg[5:0]payload_len;
reg[1:0]addr;
begin
@(negedge clock);
wait(~busy)
@(negedge clock);
payload_len=6'd16;
addr=2'b01; //valid packet
header={payload_len,addr};
parity=8'd0;
data_in=header;
pkt_valid=1'b1;
parity=parity^data_in;
@(negedge clock);
wait(~busy)
for(i=0;i<payload_len;i=i+1)
begin
@(negedge clock);
wait(~busy)
payload_data={$random}%256;
data_in=payload_data;
parity=parity^data_in;
end
@(negedge clock);
wait(~busy)
pkt_valid=1'b0;
data_in=parity;
end
endtask
task pkt_gen_17;
reg[7:0]payload_data,parity,header;
reg[5:0]payload_len;
reg[1:0]addr;
begin
@(negedge clock);
wait(~busy)
@(negedge clock);
payload_len=6'd17;
addr=2'b01; //valid packet
header={payload_len,addr};
parity=8'd0;
data_in=header;
pkt_valid=1'b1;
parity=parity^data_in;
@(negedge clock);
wait(~busy)
for(i=0;i<payload_len;i=i+1)
begin
@(negedge clock);
wait(~busy)
payload_data={$random}%256;
data_in=payload_data;
parity=parity^data_in;
end
@(negedge clock);
wait(~busy)
pkt_valid=1'b0;
data_in=parity;
end
endtask
initial
begin
initialize;
Resetn;
pkt_gen_14;
repeat(2)
@(negedge clock);
read_enb_0=1'b1;
wait(~vld_out_0)
@(negedge clock)
read_enb_0=1'b0;
pkt_gen_17;
repeat(2)
@(negedge clock);
read_enb_0=1'b1;
wait(~vld_out_0)
@(negedge clock)
read_enb_0=1'b0;
pkt_gen_16;
repeat(2)
@(negedge clock)
read_enb_1=1'b1;
wait(~vld_out_1)
@(negedge clock)
read_enb_1=1'b0;
#100 $finish;
end
initial
$monitor("clock=%b,resetn=%b,read_enb_0=%b,read_enb_1=%b,read_enb_2=%b,pkt_valid=%b,dat
a_in=%b,data_out_0=%b,data_out_1=%b,data_out_2=%b,vld_out_0=%b,vld_out_1=%b,vld_out_2=
%b,err=%b,busy=%b",clock,resetn,read_enb_0,read_enb_1,read_enb_2,pkt_valid,data_in,data_out_0,
data_out_1,data_out_2,vld_out_0,vld_out_1,vld_out_2,err,busy);
esndmodule