Sakshi Router Project
Sakshi Router Project
FIFO
1. RTL code
//FIFO RTL
module
fifo(clock,resetn,din,read_enb,write_enb,lfd_state,soft_reset,data_out,full
,empty);
input clock,resetn,read_enb,write_enb,lfd_state,soft_reset;
output full,empty;
parameter RAM_WIDTH=8,RAM_DEPTH=16,ADDR_SIZE=5;
input [RAM_WIDTH-1:0]din;
output reg [RAM_WIDTH-1:0]data_out;
reg [RAM_WIDTH:0]mem[RAM_DEPTH-1:0];
reg [ADDR_SIZE-1:0]wr_addr; reg [ADDR_SIZE-1:0]rd_addr; reg [6:0]count;
integer i;
reg temp;
always@(posedge clock)
begin
if(lfd_state)
temp<=lfd_state;
else
temp<=0;
end
//Write Operation
always@(posedge clock)
begin
if(~resetn)
begin
for(i=0;i<16;i=i+1)
begin
//Clear location
mem[i]<=0;
data_out<=0;
count<=0;
end
end
else if(soft_reset==1)
data_out<=1'bz;
else
begin
if(write_enb && ~full)
mem[wr_addr[3:0]]<={temp,din};
if(read_enb && ~empty)
begin
if(mem[rd_addr[3:0]][8:8]==1) //[8:8]is the header byte
begin
case(count)
0: begin //increases when writing
count<=mem[rd_addr[3:0]][7:2]+1; //[7:2]length of payload
data_out<=mem[rd_addr[3:0]];
end
default:begin //decreases when reading
count<=count-1;
data_out<=mem[rd_addr[3:0]];
end
endcase
end
else
begin
case(count)
0:begin
data_out<=8'bz;
end
default:begin
count<=count-1;
data_out<=mem[rd_addr[3:0]];
end
endcase
endendendend
always @(posedge clock)
begin
if(~resetn||soft_reset)
begin
wr_addr<=0;
end
else
begin
if(write_enb && ~full)
wr_addr<=wr_addr+1'b1;
end end
always @(posedge clock)
begin
if(~resetn||soft_reset)
begin
rd_addr<=0;
end
else
if(read_enb && ~empty)
rd_addr<=rd_addr+1'b1;
/* if(soft_reset==1) data_out=1'bz;*/
end
endmodule
2. Testbench code
//FIFO testbench
module fifo_tb();
parameter RAM_WIDTH=8,ADDR_SIZE=5,RAM_DEPTH=16;
reg clock,read_enb,write_enb,resetn,lfd_state,soft_reset; parameter
cycle=10;
reg [RAM_WIDTH-1:0]din; wire full,empty;
wire [RAM_WIDTH-1:0]data_out;
fifo
dut(clock,resetn,din,read_enb,write_enb,lfd_state,soft_reset,data_out,full,
empty); always #(cycle/2) clock=~clock;
initial begin
clock=1'b0;soft_reset=1'b0; rst1;
pkt_gen; @(negedge clock); soft_reset=1'b1; read_enb=1'b1; #100 $finish;
end
initial begin rst1;
@(negedge clock); lfd_state=1; @(negedge clock);
lfd_state=0; end
task rst1; begin resetn=1'b0;
@(negedge clock); resetn=1'b1;
end endtask
task pkt_gen;
reg [7:0]payload_data,parity,header;
reg [5:0]payload_len;
reg [1:0]addr;
begin
@(negedge clock);
write_enb=1'b1;
payload_len=1'b1+4'b1110;
addr={$random}%3;
header={payload_len,addr};
din=header;
for(i=0;i<payload_len;i=i+1)
begin
payload_data={$random}%256;
din=payload_data;
@(negedge clock);
end
parity=($random)%256;
din=parity;
end
endtask
initial
$monitor($time,"clock=%b,resetn=%b,read_enb=%b,write_enb=%b,din=
%d,lfd_state=%b,soft_reset=%b,data_out=%d,full=%d,empty=
%d",clock,resetn,read_enb,write_enb,din,lfd_state,soft_reset,data_out,full,
empty);
endmodule
3. Simulation waves
4. Synthesis circuits
Synchronizer
1. RTL code
//SYNCHRONIZER RTL
module
sync(clock,resetn,data_in,detect_add,full_0,full_1,full_2,empty_0,empty_1,e
mpty_2,write_enb_reg,read_enb_0,read_enb_1,read_enb_2,write_enb,fifo_full,v
ld_out_0,vld_out_1,vld_out_2,soft_reset_0,soft_reset_1,soft_reset_2);
input
clock,resetn,detect_add,full_0,full_1,full_2,empty_0,empty_1,empty_2,write_
enb_reg,read_enb_0,read_enb_1,read_enb_2;
input [1:0]data_in;
output reg fifo_full,soft_reset_0,soft_reset_1,soft_reset_2;
output vld_out_0,vld_out_1,vld_out_2;
output reg [2:0]write_enb; reg [1:0]temp;
reg [4:0]count_0,count_1,count_2;
always@(posedge clock)
begin
if(detect_add)
temp<=data_in;
end
alwas @(*)
begin
case(temp)
2'b00: fifo_full=full_0;
2'b01: fifo_full=full_1;
2'b10: fifo_full=full_2;
default: fifo_full=1'b0;
endcase end
always @(*)
end endtask
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,empty_1,em
pty_2,write_enb_reg,read_enb_0,read_enb_1,read_enb_2,write_enb,fifo_full,vl
d_out_0,vld_out_1,vld_out_2,soft_reset_0,soft_reset_1,soft_reset_2) ;
end endmodule
3. Simulation waveforms
4. Synthesis ciircuit
FSM:
1. RTL code
//FSM RTL
module
fsm(clock,resetn,pkt_valid,data_in,fifo_full,fifo_empty_0,fifo_empty_1,fifo
_empty_2,soft_reset_0,soft_reset_1,soft_reset_2,parity_done,low_pkt_valid,w
rite_enb_reg,detect_add,ld_state,laf_state,lfd_state,full_state,rst_int_reg
,busy);
input
clock,resetn,pkt_valid,fifo_full,fifo_empty_0,fifo_empty_1,fifo_empty_2,sof
t_reset_0,soft_reset_1,soft_reset_2,parity_done,low_pkt_valid;
input [1:0]data_in;
output
write_enb_reg,detect_add,ld_state,laf_state,lfd_state,full_state,rst_int_re
g; output reg busy;
reg [1:0]temp1;
parameter
DECODE_ADDRESS=3'b000,WAIT_TILL_EMPTY=3'b001,LOAD_FIRST_DATA=3'b010,LOAD_DA
TA=3'b011,
LOAD_PARITY=3'b100,FIFO_FULL_STATE=3'b101,LOAD_AFTER_FULL=3'b110,CHECK_PARI
TY_ERROR=3'b 111;
reg [2:0]state,next_state;
always@(posedge clock) begin
if(detect_add) temp1<=data_in; end
always @(posedge clock) begin
if(~resetn) state<=DECODE_ADDRESS;
else if(soft_reset_0 && temp1==2'b00) state<=DECODE_ADDRESS;
else if(soft_reset_1 && temp1==2'b01) state<=DECODE_ADDRESS;
else if(soft_reset_2 && temp1==2'b10) state<=DECODE_ADDRESS;
else
state<=next_state; end
always @(*) begin
next_state=DECODE_ADDRESS; case(state)
3'b000:begin
if((pkt_valid && data_in==0 && fifo_empty_0)||(pkt_valid && data_in==1 &&
fifo_empty_1)||(pkt_valid && data_in==2 && fifo_empty_2))
next_state=LOAD_FIRST_DATA;
else if((pkt_valid && data_in==0 && ~fifo_empty_0)||(pkt_valid &&
data_in==1 && ~fifo_empty_1)||(pkt_valid && data_in==2 && ~fifo_empty_2))
next_state=WAIT_TILL_EMPTY; else next_state=DECODE_ADDRESS;
end
3'b001:begin
if(~fifo_empty_0 && temp1==2'b00||(~fifo_empty_0 && temp1==2'b01)||
(~fifo_empty_0 && temp1==2'b10))
next_state=WAIT_TILL_EMPTY;
else if(fifo_empty_0 && temp1==2'b00||fifo_empty_1 && temp1==2'b01||
fifo_empty_2 && temp1==2'b10)
next_state=LOAD_FIRST_DATA;
end3'b010:begin
next_state=LOAD_DATA;
end
3'b011:begin
if(fifo_full)
next_state=FIFO_FULL_STATE;
else if(fifo_full==0 && pkt_valid==0)
next_state=LOAD_PARITY; else
next_state=LOAD_DATA;
end
3'b100:begin
next_state=CHECK_PARITY_ERROR;
end 3'b101:begin
if(fifo_full) next_state=FIFO_FULL_STATE; else next_state=LOAD_AFTER_FULL;
end
3'b110:begin if(parity_done)
next_state=DECODE_ADDRESS;
else if(parity_done==0&& low_pkt_valid==1) next_state=LOAD_PARITY;
else if(parity_done==0&& low_pkt_valid==0) next_state=LOAD_DATA;
end
3'b111:begin if(fifo_full)
next_state=FIFO_FULL_STATE;
else
next_state=DECODE_ADDRESS; end
endcase
end
assign detect_add= (state==DECODE_ADDRESS); assign lfd_state=
(state==LOAD_FIRST_DATA); always @(state)
begin case(state)
3'b011:busy=1'b0;
3'b000:busy=1'b0; default:busy=1'b1;
endcase
end
assign ld_state=(state==LOAD_DATA);
assign write_enb_reg=((state==LOAD_DATA)||state==LOAD_PARITY||
state==LOAD_AFTER_FULL);
/* always (posedge clock) begin
case(state)
3'b000:temp1<=1'b0; 3'b001:temp1<=1'b0; 3'b010:temp1<=temp1; 3'b011
endcase
end */
assign full_state=(state==FIFO_FULL_STATE); assign laf_state=
(state==LOAD_AFTER_FULL);
assign rst_int_reg=(low_pkt_valid==1'b0)? (state==CHECK_PARITY_ERROR):0;
endmodule
2. Testbench code
//FSM testbench
module fsm_tb();
reg
clock,resetn,pkt_valid,fifo_full,fifo_empty_0,fifo_empty_1,fifo_empty_2,sof
t_reset_0,soft_reset_1,soft_reset_2,parity_done,low_pkt_valid;
reg [1:0]data_in;
wire
write_enb_reg,detect_add,ld_state,laf_state,lfd_state,full_state,rst_int_re
g,busy;
fsm
dut(clock,resetn,pkt_valid,data_in,fifo_full,fifo_empty_0,fifo_empty_1,fifo
_empty_2,soft_reset_0,soft_reset_1,soft_reset_2,parity_done,low_pkt_valid,w
rite_enb_reg,detect_add,ld_state,laf_state,lfd_state,full_state,rst_int_reg
,busy);
parameter cycle=10;
always #(cycle/2) clock=~clock;
initial begin
clock=1'b0; rst1;
input_soft(1,1,1); @(negedge clock); input_soft(0,0,0);
//1st senario input_data(2'b10);
input_full(1,1,0,0); input_empty(1,1,1); repeat(5) @(negedge clock);
input_full(1,0,0,1); repeat(6)
@(negedge clock);
//2nd senario rst1; input_data(2'b01);
input_full(1,1,0,0); input_empty(1,1,1); repeat(5) @(negedge clock);
input_full(1,0,1,1);
repeat(2)
@(negedge clock);
//3rd swnario rst1; input_data(2'b00);
input_full(1,1,1,1); input_empty(1,1,1); repeat(5) @(negedge clock);
input_full(1,0,0,0); repeat(3) @(negedge clock);
input_full(0,0,0,0); repeat(2)
@(negedge clock);
//5th swnario
rst1; input_data(2'b10); input_full(1,1,1,1); input_empty(1,1,0); repeat(2)
@(negedge clock);
input_empty(1,1,1); repeat(2) @(negedge clock);
input_full(0,0,0,1); repeat(3) @(negedge clock);
input_full(0,1,1,0); repeat(2) @(negedge clock);
input_full(0,0,1,0);
4. Synthesis circuit
Register:
1. RTL code
//REGISTER RTL
module
regi(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_pkt_valid,dout);
input
clock,resetn,pkt_valid,fifo_full,detect_add,ld_state,laf_state,full_state,l
fd_state,rst_int_reg;
input [7:0]data_in;
output reg err,parity_done,low_pkt_valid; output reg [7:0]dout;
reg [7:0]header_reg,fifo_full_reg,parity_reg,pkt_parity_reg; always
@(posedge clock)
begin
if(~resetn|| detect_add) parity_done<=0;
else if(ld_state && ~fifo_full && ~pkt_valid)
parity_done<=1'b1;
else if(laf_state && low_pkt_valid) begin
if(~parity_done)
parity_done<=1'b1;
endend
always @(posedge clock) begin
if(~resetn || rst_int_reg)
low_pkt_valid<=0;
else if(ld_state==1 && pkt_valid==0) low_pkt_valid<=1;
end
always @(posedge clock) begin
if(~resetn)
begin header_reg<=0; fifo_full_reg<=0; pkt_parity_reg<=0; end
else begin if((detect_add && pkt_valid) && data_in[1:0]!=2'b11)
header_reg<=data_in;
else if(~pkt_valid && ld_state)
pkt_parity_reg<=data_in;
else if(ld_state && fifo_full==1) fifo_full_reg<=data_in;
endend
always @(posedge clock) begin
if(~resetn) dout<=0;
else begin
if(lfd_state)
dout<=header_reg;
else if(ld_state && ~fifo_full) dout<=data_in;
else if(laf_state) dout<=fifo_full_reg;
endend
always @(posedge clock) begin if(~resetn)
parity_reg<=0;
else if(pkt_valid && lfd_state) parity_reg<=0^header_reg;
else if(pkt_valid && ld_state && ~full_state)
parity_reg<=parity_reg^data_in;
end
always @(posedge clock) begin
if(~resetn)
err<=0;
else if(parity_done) begin
if(parity_reg!=pkt_parity_reg) err<=1'b1;
else
err<=0;
end
else err<=0; end
endmodule
2. Testbench code
//REGISTER testbench
module regi_tb();
reg
clock,resetn,pkt_valid,fifo_full,detect_add,ld_state,laf_state,full_state,l
fd_state,rst_int_reg; reg [7:0]data_in;
wire err,parity_done,low_pkt_valid; wire [7:0]dout;
regi
dut(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_pkt_valid,dout);
parameter cycle=10; integer i;
always #(cycle/2) clock=~clock; initial
begin clock=0; rst1();
detectaddress(0); loadfirstdata(0); fullstate1(0); fifofull1(0);
loadafterdata(0); loadstate(0) ; rst_int(0);
pkt_gen;
repeat(2) @(negedge clock);
//err rst1();
pkt_gen;
repeat(2) @(negedge clock);
#100 $finish; end
task rst1; begin resetn=1'b0;
@(negedge clock); resetn=1'b1;
end endtask
task pkt_gen;
reg [7:0]payload_data,parity,header; reg [5:0]payload_len;
reg [1:0]addr; begin detectaddress(1); packet_valid(1);
//@(negedge clock); payload_len=1'b1+4'b1110; addr={$random}%3;
header={payload_len,addr}; data_in=header; parity=0^header; @(negedge
clock);
detectaddress(0); loadfirstdata(1); @(negedge clock); loadfirstdata(0);
loadstate(1) ;/*repeat(2) @(negedge clock);*/ for(i=0;i<payload_len;i=i+1)
begin payload_data={$random}%256; data_in=payload_data;
parity=parity^data_in; @(negedge clock);
end fifofull1(1); repeat(2)
@(negedge clock); fifofull1(0); packet_valid(0);
//parity=($random)%256; data_in=parity;
end endtask
//rst_int
task rst_int(input rst2); begin
rst_int_reg=rst2; end
endtask//packet valid
task packet_valid(input pkt1); begin
pkt_valid=pkt1; end
endtask
//loadstate
task loadstate(input ld1); begin
ld_state=ld1; end
endtask
//loadafterdata
task loadafterdata(input laf1); begin
laf_state=laf1; end
endtask
//detect_add
task detectaddress(input det1); begin
detect_add=det1; end
endtask
//fifo_full
task fifofull1(input fifo); begin
fifo_full=fifo; endendtask
//loadfirstdata
task loadfirstdata(input lfd1); begin
lfd_state=lfd1; end
endtask
//fullstate
task fullstate1(input full); begin
full_state=full; end
endtask
endmodule
3. Simulation waveforms
4. Synthesis circuit
TOP MODULE:
1. RTL code
//TOP Module RTL
module
top(clock,resetn,pkt_valid,read_enb_0,read_enb_1,read_enb_2,data_in,data_ou
t_1,data_out_2,data_out_0,vld_out_0,vld_out_1,vld_out_2,err,busy);
input clock,resetn,pkt_valid,read_enb_0,read_enb_1,read_enb_2; input
[7:0]data_in;
output [7:0]data_out_1,data_out_2,data_out_0; output
vld_out_0,vld_out_1,vld_out_2;
output err,busy; wire [7:0]dout;
wire [2:0]write_enb;
fsm
fsm1(clock,resetn,pkt_valid,data_in[1:0],fifo_full,empty_0,empty_1,empty_2,
soft_reset_0,soft_reset_1,
soft_reset_2,parity_done,low_pkt_valid,write_enb_reg,detect_add,ld_state,la
f_state,lfd_state,full_state,rst_int_reg,busy);
sync
synchronizer(clock,resetn,data_in[1:0],detect_add,full_0,full_1,full_2,empt
y_0,empty_1,empty_2,write_enb_reg,read_enb_0,read_enb_1,read_enb_2,write_en
b,fifo_full,vld_out_0,vld_out_1,vld_out_2,soft_reset_0,soft_reset_1,soft_re
set_2);
regi
r1(clock,resetn,pkt_valid,data_in,fifo_full,detect_add,ld_state,laf_state,f
ull_state,lfd_state,rst_int_reg,err,parity_done,low_pkt_valid,dout);
fifo
fifo0(.clock(clock),.resetn(resetn),.din(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));
fifo
fifo1(.clock(clock),.resetn(resetn),.din(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));
fifo
fifo2(.clock(clock),.resetn(resetn),.din(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
2. Testbench code
//TOP testbench
module top_tb();
reg clock,resetn,pkt_valid,read_enb_0,read_enb_1,read_enb_2; reg
[7:0]data_in;
wire [7:0]data_out_1,data_out_2,data_out_0; wire
vld_out_0,vld_out_1,vld_out_2;
wire err,busy; parameter cycle=10; integer i;
top
top1(clock,resetn,pkt_valid,read_enb_0,read_enb_1,read_enb_2,data_in,data_o
ut_1,data_out_2,data_out_0,vld_out_0,vld_out_1,vld_out_2,err,busy);
always #(cycle/2) clock=~clock; initial
begin clock=1'b0; rst1; pkt_gen_14; repeat(8)
@(negedge clock); read_enb_2=1'b1; #100 $finish;
end
task rst1; begin 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) payload_len=16; addr={$random}%3;
header={payload_len,addr}; parity=0;
pkt_valid=1;
data_in=header ; parity=parity^header;
4. Synthesis circuit