From b05a2080915f7b0be689d2da5239b635f726aeba Mon Sep 17 00:00:00 2001 From: Naga Sitaram M Date: Wed, 11 Oct 2023 14:08:15 +0530 Subject: [PATCH] NOC --- RISC_V/NOC/router_fifo.v | 143 ++++++++++++++++++++++++++++++ RISC_V/NOC/router_fsm.v | 142 +++++++++++++++++++++++++++++ RISC_V/NOC/router_reg.v | 119 +++++++++++++++++++++++++ RISC_V/NOC/router_sync.v | 177 +++++++++++++++++++++++++++++++++++++ RISC_V/NOC/router_top.v | 36 ++++++++ RISC_V/NOC/router_top_tb.v | 123 ++++++++++++++++++++++++++ 6 files changed, 740 insertions(+) create mode 100644 RISC_V/NOC/router_fifo.v create mode 100644 RISC_V/NOC/router_fsm.v create mode 100644 RISC_V/NOC/router_reg.v create mode 100644 RISC_V/NOC/router_sync.v create mode 100644 RISC_V/NOC/router_top.v create mode 100644 RISC_V/NOC/router_top_tb.v diff --git a/RISC_V/NOC/router_fifo.v b/RISC_V/NOC/router_fifo.v new file mode 100644 index 0000000..ef86e17 --- /dev/null +++ b/RISC_V/NOC/router_fifo.v @@ -0,0 +1,143 @@ +module router_fifo(data_out,full,empty,clock,resetn,soft_reset,data_in,write_enb,read_enb,lfd_state); + + parameter DATA_WIDTH = 9, + DATA_DEPTH=16, + DATA_ADDR=4; + + input clock,resetn,write_enb,read_enb,soft_reset,lfd_state; + input [7:0]data_in; + + output reg [7:0]data_out; + output full,empty; + reg temp; + integer i; + reg [3:0]rd_pntr,wr_pntr; + //counters the no.of write and read signals + reg [4:0]f_e_count; + // counters the no.of payloads and parity + reg [5:0]counter; + + + reg [8:0] mem [0:15]; + + assign full = (f_e_count==5'b10000); + assign empty = (f_e_count ==5'b00000); + + + + always @(posedge clock ) begin + if (!resetn) begin + temp<=1'b0; + end + else if (soft_reset) begin + temp<=1'b0; + end + else + temp<=lfd_state; + end + //write pointer and read pointer logic + + always @(posedge clock) + begin + if(!resetn) + wr_pntr<=4'b0000; + else if (soft_reset) + wr_pntr<=4'b0000; + else if (write_enb==1 && full == 0) + wr_pntr<=wr_pntr+1'b1; + else + wr_pntr<=wr_pntr; + end + + always @(posedge clock) + begin + if(!resetn) + rd_pntr<=4'b0000; + else if (soft_reset) + rd_pntr<=4'b0000; + else if (read_enb==1 && empty == 0) + rd_pntr<=rd_pntr+1'b1; + else + rd_pntr<=rd_pntr; + end + // write operation + always @(posedge clock ) begin + if (!resetn) begin + for (i =0 ;i<16 ;i=i+1 ) begin + mem[i]<=0; + end + end + else if (soft_reset) begin + for (i =0 ;i<16 ;i=i+1 ) begin + mem[i]<=0; + end + end + else if(write_enb==1 && full==0) + begin + mem[wr_pntr]<={temp,data_in[7:0]}; + end + else + mem[wr_pntr]<=mem[wr_pntr]; + end + + // read operation + always @(posedge clock) begin + if (!resetn) begin + data_out<=8'h00; + end + else if (soft_reset) + begin + data_out<=8'hz; + end + else + if(counter==6'b000000) begin + data_out<=9'bz; + end + else if(read_enb==1 && empty==0) begin + data_out<=mem[rd_pntr]; + end + end + + // counterer operation for full and empty + always @(posedge clock) begin + if (!resetn) + begin + f_e_count<=5'b00000; + end + else if (soft_reset) + begin + f_e_count<=5'b00000; + end + else + begin + case({write_enb,read_enb}) + 2'b10:if (f_e_count != DATA_DEPTH) + begin + f_e_count<=f_e_count+1; + end + 2'b01:if (f_e_count != 5'b00000) + begin + f_e_count<=f_e_count-1; + end + 2'b00:f_e_count<=f_e_count; + 2'b11:f_e_count<=f_e_count; + + default : f_e_count<=f_e_count; + endcase + end + end + + always@(posedge clock) + begin + //check the msb value of data and if its 1 its a header and then take payload length+1 as count(1st bit for header; last 2 bits for address) + if(mem[rd_pntr][8] && read_enb && ~empty) + counter<=mem[rd_pntr][7:2]+1; + + //decrement value until count becomes zero or until count is a non zero value + else if((counter!=0) && read_enb && ~empty) + counter<=counter-1; + else + counter<=counter; + end + +endmodule diff --git a/RISC_V/NOC/router_fsm.v b/RISC_V/NOC/router_fsm.v new file mode 100644 index 0000000..ae10db0 --- /dev/null +++ b/RISC_V/NOC/router_fsm.v @@ -0,0 +1,142 @@ +module router_fsm(input clock,resetn,pkt_valid, + input [1:0] data_in, + input fifo_full,fifo_empty_0,fifo_empty_1,fifo_empty_2,fifo_empty_3,soft_reset_0,soft_reset_1,soft_reset_2,soft_reset_3,parity_done, low_packet_valid, + output write_enb_reg,detect_add,ld_state,laf_state,lfd_state,full_state,rst_int_reg,busy); + + parameter DECODE_ADDRESS = 4'b0001, + WAIT_TILL_EMPTY = 4'b0010, + LOAD_FIRST_DATA = 4'b0011, + LOAD_DATA = 4'b0100, + LOAD_PARITY = 4'b0101, + FIFO_FULL_STATE = 4'b0110, + LOAD_AFTER_FULL = 4'b0111, + CHECK_PARITY_ERROR = 4'b1000; + +reg [3:0] present_state, next_state; +reg [1:0] temp; +wire temp_lfd_state; +//temp logic +always@(posedge clock) + begin + if(~resetn) + temp<=2'b0; + else if(detect_add == 2'b00 || 2'b01 || 2'b10 || 2'b11) // decides the address of out channel + temp<=data_in; + end +// reset logic for states +always@(posedge clock) + begin + if(!resetn) + present_state<=DECODE_ADDRESS; // hard reset + else if (((soft_reset_0) && (temp==2'b00)) || ((soft_reset_1) && (temp==2'b01)) || ((soft_reset_2) && (temp==2'b10)) || ((soft_reset_3) && (temp==2'b11))) //if there is soft_reset and also using same channel so we do here and opertion + + present_state<=DECODE_ADDRESS; + + else + present_state<=next_state; + + end +//state machine logic + +always@(*) + begin + case(present_state) + DECODE_ADDRESS: // decode address state + begin + if((pkt_valid && (data_in==2'b00) && fifo_empty_0)|| (pkt_valid && (data_in==2'b01) && fifo_empty_1)|| (pkt_valid && (data_in==2'b10) && fifo_empty_2) || (pkt_valid && (data_in==2'b11) && fifo_empty_3)) + + next_state<=LOAD_FIRST_DATA; //lfd_state + + else if((pkt_valid && (data_in==2'b00) && !fifo_empty_0)||(pkt_valid && (data_in==2'b01) && !fifo_empty_1)||(pkt_valid && (data_in==2'b10) && !fifo_empty_2) || (pkt_valid && (data_in==2'b11) && !fifo_empty_3)) + next_state<=WAIT_TILL_EMPTY; //wait till empty state + + else + next_state<=DECODE_ADDRESS; // same state + end + + LOAD_FIRST_DATA: // load first data state + begin + next_state<=LOAD_DATA; + end + + WAIT_TILL_EMPTY: //wait till empty state + begin + if((fifo_empty_0 && (temp==2'b00))||(fifo_empty_1 && (temp==2'b01))||(fifo_empty_2 && (temp==2'b10)) || (fifo_empty_3 && (temp==2'b11))) //fifo is empty and were using same fifo + next_state<=LOAD_FIRST_DATA; + + else + next_state<=WAIT_TILL_EMPTY; + end + + LOAD_DATA: //load data + begin + if(fifo_full==1'b1) + next_state<=FIFO_FULL_STATE; + else + begin + if (!fifo_full && !pkt_valid) + next_state<=LOAD_PARITY; + else + next_state<=LOAD_DATA; + end + end + + FIFO_FULL_STATE: //fifo full state + begin + if(fifo_full==0) + next_state<=LOAD_AFTER_FULL; + else + next_state<=FIFO_FULL_STATE; + end + + LOAD_AFTER_FULL: // load after full state + begin + if(!parity_done && low_packet_valid) + next_state<=LOAD_PARITY; + else if(!parity_done && !low_packet_valid) + next_state<=LOAD_DATA; + + else + begin + if(parity_done==1'b1) + next_state<=DECODE_ADDRESS; + else + next_state<=LOAD_AFTER_FULL; + end + + end + + LOAD_PARITY: // load parity state + begin + next_state<=CHECK_PARITY_ERROR; + end + + CHECK_PARITY_ERROR: // check parity error + begin + if(!fifo_full) + next_state<=DECODE_ADDRESS; + else + next_state<=FIFO_FULL_STATE; + end + + default: //default state + next_state<=DECODE_ADDRESS; + + endcase // state machine completed + end + +// output logic + +assign detect_add=((present_state==DECODE_ADDRESS))?1:0; +assign busy=((present_state==LOAD_FIRST_DATA)||(present_state==LOAD_PARITY)||(present_state==FIFO_FULL_STATE)||(present_state==LOAD_AFTER_FULL)||(present_state==WAIT_TILL_EMPTY)||(present_state==CHECK_PARITY_ERROR))?1:0; + +assign lfd_state=(temp_lfd_state)?1:0; +assign temp_lfd_state=((present_state==LOAD_FIRST_DATA))?1:0; //1 clock cycle delay + +assign ld_state=((present_state==LOAD_DATA))?1:0; +assign write_enb_reg=((present_state==LOAD_DATA)||(present_state==LOAD_AFTER_FULL)||(present_state==LOAD_PARITY))?1:0; +assign full_state=((present_state==FIFO_FULL_STATE))?1:0; +assign laf_state=((present_state==LOAD_AFTER_FULL))?1:0; +assign rst_int_reg=((present_state==CHECK_PARITY_ERROR))?1:0; + +endmodule diff --git a/RISC_V/NOC/router_reg.v b/RISC_V/NOC/router_reg.v new file mode 100644 index 0000000..6fb6f53 --- /dev/null +++ b/RISC_V/NOC/router_reg.v @@ -0,0 +1,119 @@ +module router_reg(data_out,err,parity_done,low_packet_valid,clock,resetn,pkt_valid,data_in,fifo_full,detect_add,ld_state,laf_state,full_state,lfd_state,rst_int_reg); + + input clock,resetn,pkt_valid; + input [7:0]data_in; + input fifo_full,detect_add,ld_state,laf_state,full_state,lfd_state,rst_int_reg; + + output reg err,parity_done,low_packet_valid; + output reg [7:0]data_out; + + reg [7:0]header_byte,fifo_full_state,internal_parity,packet_parity; + + + +//low_packet valid +always@(posedge clock) + begin + if(!resetn) + low_packet_valid<=1'b0; + else + begin + if(rst_int_reg) + low_packet_valid<=1'b0; + if(ld_state==1'b1 && pkt_valid==1'b0) + low_packet_valid<=1'b1; + end + end + +//data_out +always@(posedge clock) + + begin + if(!resetn) + data_out<=8'b0; + else + begin + if(detect_add && pkt_valid) + header_byte<=data_in; + else if(lfd_state) + data_out<=header_byte; + else if(ld_state && !fifo_full) + data_out<=data_in; + else if(ld_state && fifo_full) + fifo_full_state<=data_in; + else + begin + if(laf_state) + data_out<=fifo_full_state; + end + end + end + +//parity done +always@(posedge clock) + begin + if(!resetn) + begin + parity_done<=1'b0; + end + + else + begin + if(ld_state && !fifo_full && !pkt_valid) + parity_done<=1'b1; + else if(laf_state && low_packet_valid && !parity_done) + parity_done<=1'b1; + else + begin + if(detect_add) + parity_done<=1'b0; + end + end + end + +// internal parity +always@(posedge clock) + begin + if(!resetn) + internal_parity<=8'b0; + else if(lfd_state) + internal_parity<=internal_parity ^ header_byte; + else if(ld_state && pkt_valid && !full_state) + internal_parity<=internal_parity ^ data_in; + else + begin + if (detect_add) + internal_parity<=8'b0; + end + end + +//packet_parity +always@(posedge clock) + begin + if(!resetn) + packet_parity<=8'b0; + else + begin + if(!pkt_valid && ld_state) + packet_parity<=data_in; + end + end + +//error +always@(posedge clock) + begin + if(!resetn) + err<=1'b0; + else + begin + if(parity_done) + begin + if(internal_parity!=packet_parity) + err<=1'b1; + else + err<=1'b0; + end + end + end + +endmodule diff --git a/RISC_V/NOC/router_sync.v b/RISC_V/NOC/router_sync.v new file mode 100644 index 0000000..4227139 --- /dev/null +++ b/RISC_V/NOC/router_sync.v @@ -0,0 +1,177 @@ +module router_sync(write_enb,fifo_full,vld_out_0,vld_out_1,vld_out_2,vld_out_3,soft_reset_0,soft_reset_1,soft_reset_2,soft_reset_3,clock,resetn,data_in,detect_add,full_0,full_1,full_2,full_3,empty_0,empty_1,empty_2,empty_3,write_enb_reg,read_enb_0,read_enb_1,read_enb_2,read_enb_3); + + output reg [3:0]write_enb; + output vld_out_0,vld_out_1,vld_out_2,vld_out_3; + output reg fifo_full,soft_reset_0,soft_reset_1,soft_reset_2,soft_reset_3; + + input [1:0]data_in; + + input clock,resetn,detect_add,write_enb_reg; + input full_0,full_1,full_2,full_3,empty_0,empty_1,empty_2,empty_3,read_enb_0,read_enb_1,read_enb_2,read_enb_3; + + reg [1:0]temp_data_in; + reg [5:0]count_0,count_1,count_2,count_3; + + + assign vld_out_0=~empty_0; + assign vld_out_1=~empty_1; + assign vld_out_2=~empty_2; + assign vld_out_3=~empty_3; + + //data_in + always @(posedge clock) begin + if(!resetn) begin + temp_data_in<=2'b0; + end + else if (detect_add) begin + temp_data_in<= data_in; + end + end + + //write enable + always @(*) begin + if (!resetn) begin + write_enb<=4'b0000; + end + else if(write_enb_reg) + begin + case(temp_data_in) + 2'b00: write_enb=4'b0001; + 2'b01: write_enb=4'b0010; + 2'b10: write_enb=4'b0100; + 2'b11: write_enb=4'b1000; + default write_enb=4'b0000; + endcase + end + else + write_enb=4'b0000; + end + + //fifo operation + always @(*) begin + if(!resetn) begin + fifo_full=1'b0; + end + else + begin + case(temp_data_in) + 2'b00: fifo_full=full_0; + 2'b01: fifo_full=full_1; + 2'b10: fifo_full=full_2; + 2'b11: fifo_full=full_3; + default fifo_full=1'b0; + endcase + end + + end + + + //soft reset counter + // counter 0 + always@(posedge clock) + begin + if(!resetn) + count_0<=5'b0; + else if(vld_out_0) + begin + if(!read_enb_0) + begin + if(count_0==5'b11110) + begin + soft_reset_0<=1'b1; + count_0<=1'b0; + end + else + begin + count_0<=count_0+1'b1; + soft_reset_0<=1'b0; + end + end + else + count_0<=5'd0; + end + else + count_0<=5'd0; + end + + //counter 1 + always@(posedge clock) + begin + if(!resetn) + count_1<=5'b0; + else if(vld_out_1) + begin + if(!read_enb_1) + begin + if(count_1==5'b11110) + begin + soft_reset_1<=1'b1; + count_1<=1'b0; + end + else + begin + count_1<=count_1+1'b1; + soft_reset_1<=1'b0; + end + end + else + count_1<=5'd0; + end + else + count_1<=5'd0; + end + //counter 2 + always@(posedge clock) + begin + if(!resetn) + count_2<=5'b0; + else if(vld_out_2) + begin + if(!read_enb_2) + begin + if(count_2==5'b11110) + begin + soft_reset_2<=1'b1; + count_2<=1'b0; + end + else + begin + count_2<=count_2+1'b1; + soft_reset_2<=1'b0; + end + end + else + count_2<=5'd0; + end + else + count_2<=5'd0; + end + + //counter 3 + always@(posedge clock) + begin + if(!resetn) + count_3<=5'b0; + else if(vld_out_3) + begin + if(!read_enb_3) + begin + if(count_3==5'b11110) + begin + soft_reset_3<=1'b1; + count_3<=1'b0; + end + else + begin + count_3<=count_3+1'b1; + soft_reset_3<=1'b0; + end + end + else + count_3<=5'd0; + end + else + count_3<=5'd0; + end + +endmodule diff --git a/RISC_V/NOC/router_top.v b/RISC_V/NOC/router_top.v new file mode 100644 index 0000000..f387d50 --- /dev/null +++ b/RISC_V/NOC/router_top.v @@ -0,0 +1,36 @@ +module router_top(data_out_0,data_out_1,data_out_2,data_out_3,vld_out_0,vld_out_1,vld_out_2,vld_out_3,error,busy,clock,resetn,read_enb_0,read_enb_1,read_enb_2,read_enb_3,data_in,pkt_valid); + + output [7:0] data_out_0,data_out_1,data_out_2,data_out_3; + output vld_out_0,vld_out_1,vld_out_2,vld_out_3,error,busy; + + input clock,resetn,read_enb_0,read_enb_1,read_enb_2,read_enb_3,pkt_valid; + input [7:0] data_in; + + wire [7:0] data_in_out; + wire [3:0] write_enb; + + // Instantiating sub-modules + // FIFO-0 + router_fifo FIFO_0(data_out_0,full_0,fifo_empty_0,clock,resetn,soft_reset_0,data_in_out,write_enb[0],read_enb_0,lfd_state); + + //FIFO-1 + router_fifo FIFO_1(data_out_1,full_1,fifo_empty_1,clock,resetn,soft_reset_1,data_in_out,write_enb[1],read_enb_1,lfd_state); + + //FIFO-2 + router_fifo FIFO_2(data_out_2,full_2,fifo_empty_2,clock,resetn,soft_reset_2,data_in_out,write_enb[2],read_enb_2,lfd_state); + + //FIFO-3 + router_fifo FIFO_3(data_out_3,full_3,fifo_empty_3,clock,resetn,soft_reset_3,data_in_out,write_enb[3],read_enb_3,lfd_state); + + // Synchronizer + router_sync SYNC(write_enb,fifo_full,vld_out_0,vld_out_1,vld_out_2,vld_out_3,soft_reset_0,soft_reset_1,soft_reset_2,soft_reset_3,clock,resetn,data_in[1:0],detect_add,full_0,full_1,full_2,full_3,fifo_empty_0,fifo_empty_1,fifo_empty_2,fifo_empty_3,write_enb_reg,read_enb_0,read_enb_1,read_enb_2,read_enb_3); + + //FSM controller + router_fsm FSM(clock,resetn,pkt_valid,data_in[1:0],fifo_full,fifo_empty_0,fifo_empty_1,fifo_empty_2,fifo_empty_3,soft_reset_0,soft_reset_1,soft_reset_2,soft_reset_3,parity_done, low_packet_valid,write_enb_reg,detect_add,ld_state,laf_state,lfd_state,full_state,rst_int_reg,busy); + + //Register + router_reg REG(data_in_out,error,parity_done,low_packet_valid,clock,resetn,pkt_valid,data_in,fifo_full,detect_add,ld_state,laf_state,full_state,lfd_state,rst_int_reg); + + +endmodule + diff --git a/RISC_V/NOC/router_top_tb.v b/RISC_V/NOC/router_top_tb.v new file mode 100644 index 0000000..f4adac4 --- /dev/null +++ b/RISC_V/NOC/router_top_tb.v @@ -0,0 +1,123 @@ +module router_top_tb(); + + reg clock,resetn,read_enb_0,read_enb_1,read_enb_2,read_enb_3,pkt_valid; + reg [7:0] data_in; + + wire [7:0]data_out_0,data_out_1,data_out_2,data_out_3; + wire vld_out_0,vld_out_1,vld_out_2,vld_out_3,error,busy; + + integer i; + + router_top DUT(data_out_0,data_out_1,data_out_2,data_out_3,vld_out_0,vld_out_1,vld_out_2,vld_out_3,error,busy,clock,resetn,read_enb_0,read_enb_1,read_enb_2,read_enb_3,data_in,pkt_valid); + + always begin + clock=1'b0; + forever #5 clock=~clock; + end + + task resetnip; + begin + @(negedge clock); + resetn=1'b0; + @(negedge clock); + resetn=1'b1; + end + endtask + + task packet_gen_14; + 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'b00; // valid packet + header={payload_len,addr}; + parity=0; + data_in=header; + pkt_valid=1; + parity=parity^header; + + @(negedge clock); + wait(~busy) + for (i =0;i