OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [rtl/] [src_noc/] [debug.v] - Rev 56

Compare with Previous | Blame | View Log

`timescale 1ns / 1ps
 
/**************************************
* Module: debug
* Date:2019-04-01  
* Author: alireza     
*
* Description: this file contain modules which are used for error checking/debiging of the NoC. 
***************************************/
 
//check if flits are recived in correct order in a VC
 
module check_flit_chanel_type_is_in_order #(
    parameter V=4,
    parameter PCK_TYPE = "SINGLE_FLIT",
    parameter MIN_PCK_SIZE=2
)(
    hdr_flg_in,
    flit_in_wr,
    tail_flg_in,
    vc_num_in,    
    clk,
    reset  
 
);
 
    input clk, reset;
    input hdr_flg_in, tail_flg_in, flit_in_wr;
    input [V-1 : 0] vc_num_in;
 
 
 
 
    wire [V-1 : 0] vc_num_hdr_wr, vc_num_tail_wr,vc_num_bdy_wr ;
    wire [V-1 : 0] hdr_passed;
    reg  [V-1 : 0] hdr_passed_next;
    wire [V-1 : 0] single_flit_pck;
 
    assign  vc_num_hdr_wr =(hdr_flg_in & flit_in_wr) ?    vc_num_in : 0;
    assign  vc_num_tail_wr =(tail_flg_in & flit_in_wr)?    vc_num_in : 0;
    assign  vc_num_bdy_wr =({hdr_flg_in,tail_flg_in} == 2'b00 && flit_in_wr)?    vc_num_in : 0;
    assign  single_flit_pck = vc_num_hdr_wr & vc_num_tail_wr;
    always @(*)begin
        hdr_passed_next = (hdr_passed | vc_num_hdr_wr) & ~vc_num_tail_wr; 
    end
 
    // synthesis translate_off
 
    pronoc_register #(
           .W(V)          
      ) reg2 ( 
           .in(hdr_passed_next),
           .reset(reset),    
           .clk(clk),      
           .out(hdr_passed)
      );    
 
 
 
    always @ (posedge clk ) begin 
            if(( hdr_passed & vc_num_hdr_wr)>0  )begin 
                $display("%t ERROR: a header flit is received in  an active IVC %m",$time);               
                $finish;
            end
            if((~hdr_passed & vc_num_tail_wr & ~single_flit_pck )>0 ) begin 
                $display("%t ERROR: a tail flit is received in an inactive IVC %m",$time);                
                $finish;
            end                
            if ((~hdr_passed & vc_num_bdy_wr    )>0)begin 
                $display("%t ERROR: a body flit is received in an inactive IVC %m",$time);                
                $finish;
            end
            /* verilator lint_off WIDTH */
            if((PCK_TYPE == "SINGLE_FLIT") &  flit_in_wr & ~(hdr_flg_in &  tail_flg_in )) begin 
                $display("%t ERROR: both tail and header flit flags must be asserted in SINGLE_FLIT mode %m",$time);
                $finish;
            end 
            /* verilator lint_on WIDTH */
            if( (MIN_PCK_SIZE !=1) &  flit_in_wr & hdr_flg_in &  tail_flg_in ) begin 
                $display("%t ERROR: A single flit packet is injected while the minimum packet size is set to %d.  %m",$time,MIN_PCK_SIZE);
                $finish;
            end
            //TODO check that the injected packet size meets the MIN_PCK_SIZE            
 
    end//always
    // synthesis translate_on
endmodule
 
 
 
 
 
 
module debug_mesh_tori_route_ckeck #(
    parameter T1=4,
    parameter T2=4,
    parameter T3=4,
    parameter ROUTE_TYPE = "FULL_ADAPTIVE",
    parameter V=4,
    parameter AVC_ATOMIC_EN=1,
    parameter SW_LOC = 0,
    parameter [V-1 : 0] ESCAP_VC_MASK= 4'b0001,
    parameter TOPOLOGY="MESH",
    parameter DSTPw=4,
    parameter RAw=4,
    parameter EAw=4,
    parameter DAw=EAw
)(
    reset,
    clk,
    hdr_flg_in,
    flit_in_wr,
    flit_is_tail,
    ivc_num_getting_sw_grant,
    vc_num_in,
    current_r_addr,
    dest_e_addr_in,
    src_e_addr_in,
    destport_in  
);
 
    function integer log2;
        input integer number; begin   
           log2=(number <=1) ? 1: 0;    
           while(2**log2<number) begin    
              log2=log2+1;    
           end        
        end   
    endfunction // log2 
 
 
    input reset,clk;
    input hdr_flg_in , flit_in_wr;
    input [V-1 : 0] vc_num_in, flit_is_tail,  ivc_num_getting_sw_grant;
    input [RAw-1 : 0] current_r_addr;
    input [DAw-1 : 0] dest_e_addr_in;
    input [EAw-1 : 0] src_e_addr_in;
    input [DSTPw-1 : 0]  destport_in; 
 
    localparam
      NX = T1,
      NY = T2,
      RXw = log2(NX),    // number of node in x axis
      RYw = (TOPOLOGY=="RING" || TOPOLOGY == "LINE") ? 1 : log2(NY),
      EXw = log2(NX),    // number of node in x axis
      EYw = (TOPOLOGY=="RING" || TOPOLOGY == "LINE") ? 1 : log2(NY);   // number of node in y axis
 
 
    wire [RXw-1 : 0] current_x;
    wire [EXw-1 : 0] x_dst_in,x_src_in;
    wire [RYw-1 : 0] current_y;
    wire [EYw-1 : 0] y_dst_in,y_src_in;      
 
    mesh_tori_router_addr_decode #(
    	.TOPOLOGY(TOPOLOGY),
    	.T1(T1),
    	.T2(T2),
    	.T3(T3),
    	.RAw(RAw)
    )
    r_addr_decode
    (
    	.r_addr(current_r_addr),
    	.rx(current_x),
    	.ry(current_y),
    	.valid()
    );
 
    mesh_tori_endp_addr_decode #(
    	.TOPOLOGY(TOPOLOGY),
        .T1(T1),
        .T2(T2),
        .T3(T3),
    	.EAw(EAw)
    )
    dst_addr_decode
    (
    	.e_addr(dest_e_addr_in),
    	.ex(x_dst_in),
    	.ey(y_dst_in),
    	.el( ),
    	.valid()
    );
 
    mesh_tori_endp_addr_decode #(
        .TOPOLOGY(TOPOLOGY),
        .T1(T1),
        .T2(T2),
        .T3(T3),
        .EAw(EAw)
    )
    src_addr_decode
    (
        .e_addr(src_e_addr_in),
        .ex(x_src_in),
        .ey(y_src_in),
        .el( ),
        .valid()
    );
 
 
localparam  
    LOCAL =  0, 
    NORTH =  2,  
    SOUTH =  4; 
 // synthesis translate_off 
generate
 
/* verilator lint_off WIDTH */
if(ROUTE_TYPE == "DETERMINISTIC")begin :dtrmn
/* verilator lint_on WIDTH */  
 
 
    always@( posedge clk)begin 
        if(flit_in_wr & hdr_flg_in )   
               if( destport_in[1:0]==2'b11) begin 
                    $display ( "%t\t  ERROR: destport port %x is illegal for determistic routing.  %m",$time,destport_in );                   
                    $finish;
               end
        end//if
    end//always
 
 
/* verilator lint_off WIDTH */
if(ROUTE_TYPE == "FULL_ADAPTIVE")begin :full_adpt
/* verilator lint_on WIDTH */    
 
    wire [V-1 : 0] not_empty;
    reg  [V-1 : 0] not_empty_next;
 
    pronoc_register #(
           .W(V)          
      ) reg2 ( 
           .in(not_empty_next),
           .reset(reset),    
           .clk(clk),      
           .out(not_empty)
      );
 
     always@(*) begin
        not_empty_next = not_empty;
        if(hdr_flg_in & flit_in_wr) begin
            not_empty_next = not_empty | vc_num_in;
        end//hdr_wr_in
        if((flit_is_tail & ivc_num_getting_sw_grant)>0)begin
            not_empty_next = not_empty & ~ivc_num_getting_sw_grant;
        end//tail wr out
     end//always
 
    always@( posedge clk ) begin
        if(hdr_flg_in & flit_in_wr) begin
            if( ((AVC_ATOMIC_EN==1)&& (SW_LOC!= LOCAL)) || (SW_LOC== NORTH) || (SW_LOC== SOUTH) )begin   
                if((vc_num_in  & ~ESCAP_VC_MASK)>0) begin // adaptive VCs
                    if( (not_empty & vc_num_in)>0) $display("%t  :Error AVC allocated nonatomicly in %d port %m",$time,SW_LOC);
                end
             end//( AVC_ATOMIC_EN || SW_LOC== NORTH || SW_LOC== SOUTH )
             if((vc_num_in  & ESCAP_VC_MASK)>0 && (SW_LOC== SOUTH || SW_LOC== NORTH) )  begin // escape vc
                       // if (a & b) $display("%t  :Error EVC allocation violate subfunction routing rules %m",$time);
                    if ((current_x - x_dst_in) !=0 && (current_y- y_dst_in) !=0) $display("%t  :Error EVC allocation violate subfunction routing rules src_x=%d src_y=%d dst_x%d   dst_y=%d %m",$time,x_src_in, y_src_in, x_dst_in,y_dst_in);
             end                     
         end//hdr_wr_in            
        end//always
    end //SW_LOC
 
 
    /* verilator lint_off WIDTH */ 
    if(TOPOLOGY=="MESH")begin :mesh
    /* verilator lint_on WIDTH */
        wire  [EXw-1 : 0] low_x,high_x;
        wire  [EYw-1 : 0] low_y,high_y;    
 
 
 
        assign low_x = (x_src_in < x_dst_in)?  x_src_in : x_dst_in;
        assign low_y = (y_src_in < y_dst_in)?  y_src_in : y_dst_in;
        assign high_x = (x_src_in < x_dst_in)?  x_dst_in : x_src_in;
        assign high_y = (y_src_in < y_dst_in)?  y_dst_in : y_src_in;
 
 
        always@( posedge clk)begin 
               if((current_x <low_x) | (current_x > high_x) | (current_y <low_y) | (current_y > high_y) )  
                    if(flit_in_wr & hdr_flg_in )begin 
                        $display ( "%t\t  ERROR: non_minimal routing %m",$time );
                        $finish;
                    end
 
        end
 
 
    end// mesh  
  endgenerate
 
  // synthesis translate_on
 
  endmodule
 
 
 module debug_mesh_edges #(
    parameter T1=2,
    parameter T2=2,
    parameter T3=3,
    parameter T4=3,
    parameter RAw=4,
    parameter P=5
 )(
    clk,
    current_r_addr,
    flit_out_wr_all
 );
 
    function integer log2;
        input integer number; begin   
           log2=(number <=1) ? 1: 0;    
           while(2**log2<number) begin    
              log2=log2+1;    
           end        
        end   
    endfunction // log2 
 
    input clk;
    input  [RAw-1 :  0]  current_r_addr;
    input  [P-1 :  0]  flit_out_wr_all;
 
    localparam 
        RXw = log2(T1),    // number of node in x axis
        RYw = log2(T2);    // number of node in y axis
 
 
  wire [RXw-1 : 0] current_rx;
  wire [RYw-1 : 0] current_ry;
 
    mesh_tori_router_addr_decode #(
    	.TOPOLOGY("MESH"),
    	.T1(T1),
    	.T2(T2),
    	.T3(T3),
    	.RAw(RAw)
    )
    addr_decode
    (
    	.r_addr(current_r_addr),
    	.rx(current_rx),
    	.ry(current_ry),
    	.valid()
    );
 
 
    localparam
        EAST = 1,
        NORTH = 2,
        WEST = 3,
        SOUTH = 4;
  // synthesis translate_off 
        always @(posedge clk) begin 
        /* verilator lint_off WIDTH */ 
                if(current_rx == {RXw{1'b0}}         && flit_out_wr_all[WEST]) $display ( "%t\t  ERROR: a packet is going to the WEST in a router located in first column in mesh topology %m",$time ); 
                if(current_rx == T1-1     && flit_out_wr_all[EAST]) $display ( "%t\t   ERROR: a packet is going to the EAST in a router located in last column in mesh topology %m",$time ); 
                if(current_ry == {RYw{1'b0}}         && flit_out_wr_all[NORTH])$display ( "%t\t  ERROR: a packet is going to the NORTH in a router located in first row in mesh topology %m",$time ); 
                if(current_ry == T2-1    && flit_out_wr_all[SOUTH])$display ( "%t\t  ERROR: a packet is going to the SOUTH in a router located in last row in mesh topology %m",$time); 
      /* verilator lint_on WIDTH */ 
        end//always
  // synthesis translate_on  
endmodule
 
 
/*******************
 * 
 * *****************/
 
 module check_destination_addr #(
    parameter NOC_ID=0,
    parameter TOPOLOGY = "MESH",
    parameter T1=2,
    parameter T2=2,
    parameter T3=2,
    parameter T4=2,
    parameter EAw=2,
    parameter DAw=2,
    parameter SELF_LOOP_EN="NO",
    parameter CAST_TYPE = "UNICAST",
    parameter NE=8
 )(
     dest_is_valid,
     dest_e_addr,
     current_e_addr    
 );
 
    input [DAw-1 : 0]  dest_e_addr;
    input [EAw-1 : 0]  current_e_addr;
    output dest_is_valid;
 
    // general rules
    /* verilator lint_off WIDTH */
    wire valid_dst  = (SELF_LOOP_EN   == "NO")? dest_e_addr  !=  current_e_addr : 1'b1;
    /* verilator lint_on WIDTH */
    wire valid;
    generate
    if(CAST_TYPE != "UNICAST") begin     
 
            wire [NE-1 : 0] dest_mcast_all_endp;            
 
            mcast_dest_list_decode #(
                .NOC_ID(NOC_ID)        
            ) decode (
                .dest_e_addr(dest_e_addr),
                .dest_o(dest_mcast_all_endp),
                .row_has_any_dest( ),
                .is_unicast()
            );
        //wire valid_dst_multi_r1  = (SELF_LOOP_EN   == "NO") ? ~(dest_mcast_all_endp[current_e_addr] == 1'b1) : 1'b1;
        wire valid_dst_multi_r2  = ~(dest_mcast_all_endp == {NE{1'b0}}); // there should be atleast one asserted destination
 
        assign  dest_is_valid =  valid_dst_multi_r2;// & valid_dst_multi_r1 ;  
    end else     
    /* verilator lint_off WIDTH */ 
    if(TOPOLOGY=="MESH" || TOPOLOGY == "TORUS" || TOPOLOGY=="RING" || TOPOLOGY == "LINE") begin : mesh        
   /* verilator lint_on WIDTH */ 
        mesh_tori_endp_addr_decode #(
        	.TOPOLOGY(TOPOLOGY),
        	.T1(T1),
        	.T2(T2),
        	.T3(T3),
        	.EAw(EAw)
        )
        mesh_tori_endp_addr_decode(
        	.e_addr(dest_e_addr),
        	.ex(),
        	.ey(),
        	.el(),
        	.valid(valid)
        );
       assign  dest_is_valid = valid_dst & valid;
 
    end else begin : tree
        assign  dest_is_valid = valid_dst;    
    end
    endgenerate
 
 endmodule
 
 
 
module  endp_addr_encoder #(
    parameter TOPOLOGY ="MESH",
    parameter T1=4,
    parameter T2=4,
    parameter T3=4,
    parameter EAw=4,
    parameter NE=16
)
(
    id,
    code
 );    
 
    function integer log2;
      input integer number; begin   
         log2=(number <=1) ? 1: 0;    
         while(2**log2<number) begin    
            log2=log2+1;    
         end        
      end   
    endfunction // log2 
 
    localparam NEw= log2(NE);
 
     input [NEw-1 :0] id;
     output [EAw-1 : 0] code;
 
     generate 
     /* verilator lint_off WIDTH */ 
     if(TOPOLOGY == "FATTREE" || TOPOLOGY == "TREE" ) begin : tree
     /* verilator lint_on WIDTH */ 
       fattree_addr_encoder #(
        .K(T1),
        .L(T2)
       )
       addr_encoder
       (
        .id(id),
        .code(code)
       );
 
     /* verilator lint_off WIDTH */ 
     end else if  (TOPOLOGY == "MESH" || TOPOLOGY == "TORUS" || TOPOLOGY == "RING" || TOPOLOGY == "LINE") begin :tori
     /* verilator lint_on WIDTH */ 
        mesh_tori_addr_encoder #(
            .NX(T1),
            .NY(T2),
            .NL(T3),
            .NE(NE),
            .EAw(EAw),
            .TOPOLOGY(TOPOLOGY)
        ) 
        addr_encoder
        (
            .id(id),
            .code(code)
        );
     end else if (TOPOLOGY == "FMESH") begin :fmesh
        fmesh_addr_encoder #(
            .NX(T1),
            .NY(T2),
            .NL(T3),
            .NE(NE),
            .EAw(EAw)
        )
        addr_encoder
        (
        .id(id),
        .code(code)
        );
 
     end else begin :custom
 
        assign code =id;
 
     end
     endgenerate
endmodule
 
 
module endp_addr_decoder  #(
        parameter TOPOLOGY ="MESH",
        parameter T1=4,
        parameter T2=4,
        parameter T3=4,
        parameter EAw=4,
        parameter NE=16
        )
        (
        id,
        code
        );    
 
    function integer log2;
        input integer number; begin   
            log2=(number <=1) ? 1: 0;    
            while(2**log2<number) begin    
                log2=log2+1;    
            end        
        end   
    endfunction // log2 
 
    localparam NEw= log2(NE);
 
    output [NEw-1 :0] id;
    input  [EAw-1 : 0] code;
 
    generate 
    /* verilator lint_off WIDTH */ 
    if(TOPOLOGY == "FATTREE" || TOPOLOGY == "TREE" ) begin : tree
    /* verilator lint_on WIDTH */ 
        fattree_addr_decoder #(
                .K(T1),
                .L(T2)
 
            )decoder(
                .id(id),
                .code(code)
            );
    /* verilator lint_off WIDTH */     
    end else if  (TOPOLOGY == "MESH" || TOPOLOGY == "TORUS" || TOPOLOGY == "RING" || TOPOLOGY == "LINE") begin :tori
    /* verilator lint_on WIDTH */      
        mesh_tori_addr_coder #(
            .TOPOLOGY(TOPOLOGY),
            .NX    (T1   ), 
            .NY    (T2   ), 
            .NL    (T3   ), 
            .NE    (NE   ), 
            .EAw   (EAw  )
            ) addr_coder (
            .id    (id   ), 
            .code  (code ));
      /* verilator lint_off WIDTH */          
     end else if (TOPOLOGY == "FMESH") begin :fmesh
      /* verilator lint_on WIDTH */   
        fmesh_addr_coder #(
            .NX(T1),
            .NY(T2),
            .NL(T3),
            .NE(NE),
            .EAw(EAw)
        )
        addr_coder
        (
        .id(id),
        .code(code)
        );
 
    end else begin :custom
 
        assign id = code;
 
    end
    endgenerate
endmodule  
 
 
module check_pck_size #(
    parameter NOC_ID=0,
    parameter V=2,
    parameter MIN_PCK_SIZE=2,
    parameter Fw=36,
    parameter DAw=4,
    parameter CAST_TYPE="UNICAST",
    parameter NE=4,
    parameter B=4,
    parameter LB=4
)(
    hdr_flg_in,
    flit_in_wr,
    tail_flg_in,
    vc_num_in,  
    dest_e_addr_in,
    clk,
    reset  
 
);
 
    input clk, reset;
    input hdr_flg_in, tail_flg_in, flit_in_wr;
    input [V-1 : 0] vc_num_in;
    input [DAw-1: 0] dest_e_addr_in;
 
    wire [NE-1 : 0] dest_mcast_all_endp [V-1 : 0];
    wire [31 : 0] pck_size_counter [V-1: 0];
    reg  [31 : 0] pck_size_counter_next [V-1: 0];
    wire [DAw-1 : 0] dest_e_addr [V-1:0];
    wire [V-1 : 0] vc_hdr_wr_en;
    wire [V-1 : 0] onehot;
 
    localparam MIN_B =  (B<LB)? B : LB;       
 
    genvar i;
    generate 
    for (i=0;i<V;i=i+1) begin 
 
        always @(*) begin 
            pck_size_counter_next [i] = pck_size_counter [i];
            if (vc_num_in == i)begin 
                if(flit_in_wr) begin  
                    if(hdr_flg_in) pck_size_counter_next[i]= 1;
                    else pck_size_counter_next[i]=pck_size_counter[i]+1;      
                end 
            end
        end     
 
 
        pronoc_register #(.W(32)) reg1(
            .in     (pck_size_counter_next[i]), 
            .reset  (reset ), 
            .clk    (clk   ), 
            .out    (pck_size_counter[i]   ));
 
         always @(posedge clk) begin 
            if (vc_num_in == i)begin 
                if(flit_in_wr & tail_flg_in) begin 
                    if( pck_size_counter_next[i] < MIN_PCK_SIZE) begin 
                        $display ( "%t\t  ERROR: A packet is injected to the router with packet size (%d flits) that is smaller than MIN_PCK_SIZE (%d flits) parameter  %m",$time,pck_size_counter_next[i],MIN_PCK_SIZE);
                        $finish;
                    end
                end       
            end
         end
 
        /* verilator lint_off WIDTH */   
        if(CAST_TYPE!="UNICAST") begin
        /* verilator lint_on WIDTH */   
        //Check that the size of multicast/broadcast packets <= buffer size
            assign vc_hdr_wr_en [i] = flit_in_wr & hdr_flg_in & (vc_num_in == i);
            pronoc_register_ld_en #(.W(DAw)) reg2(
                .in     (dest_e_addr_in), 
                .reset  (reset ), 
                .clk    (clk   ), 
                .ld     (vc_hdr_wr_en [i] ),
                .out    (dest_e_addr[i])
            );
 
 
            mcast_dest_list_decode #(
                .NOC_ID(NOC_ID)
            ) decode (
                .dest_e_addr(dest_e_addr[i]),
                .dest_o(dest_mcast_all_endp[i]),
                .row_has_any_dest(),
                .is_unicast()
            ); 
 
            is_onehot0 #(
                .IN_WIDTH(NE)    
            )
            one_h
            (
                .in(dest_mcast_all_endp[i]),
                .result(onehot[i])
 
            );
 
 
 
 
            always @(posedge clk) begin 
                if (vc_num_in == i)begin 
                    if(flit_in_wr & ~onehot[i])begin 
                        if(pck_size_counter_next[i]>MIN_B) begin 
                            $display ( "%t\t  ERROR: A multicast packet is injected to the router with packet size (%d flits) that is larger than the minimum router buffer size (%d flits) parameter  %m",$time,pck_size_counter_next[i],MIN_B);
                            $finish;
                        end// size
                    end//flit_wr
                end//vc_num
            end//always
 
        end//multicast
 
 
 
 
   end  //for
   endgenerate
 
 
 
endmodule
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.