local_bus_lite 配置总线分发与汇聚

顶层和时序

//
// i_clk            --\__/--\__/--\__/--\__/--\__/--\__/--\__/--\__/--\__/--\__/
// local_wr_ready   _____/------------------------------------------------------
// local_wr_valid   ___________/-----------------------\________________________
// local_wr_last    _____________________________/-----\________________________
// local_wr_addr    ___________|addrA|addrB|addrC|addrD|________________________
// local_wr_data    ___________|dataA|dataB|dataC|dataD|________________________
// local_rd_ready   _____/-----------------------------------------------\______
// local_rd_addr    _____|addrA      |addrB      |addrC      |addrD      |______
// local_rd_valid   ___________/-----\_____/-----\_____/-----\_____/-----\______
// local_rd_data    ___________|dataA      |dataB      |dataC      |dataD|______
//
module local_bus_lite#(
    parameter   DATA_WIDTH          =   32              ,
    parameter   ADDR_WIDTH          =   24              ,
    parameter   ID_WIDTH            =   8               ,
    parameter   S_NUM               =   1               ,
    parameter   M_NUM               =   16              ,
    parameter   AHEAD               =   {(S_NUM > M_NUM ? S_NUM : M_NUM){1'b1}}//1 : valid is first ; 0 : ready is first
)(
    input                           i_clk               ,
    input                           i_rst               ,
    //from Master
    output  [S_NUM-1:0]             s_wr_ready          ,
    input   [S_NUM-1:0]             s_wr_valid          ,
    input   [S_NUM-1:0]             s_wr_last           ,
    input   [S_NUM*DATA_WIDTH-1:0]  s_wr_data           ,
    input   [S_NUM*ADDR_WIDTH-1:0]  s_wr_addr           ,
    input   [S_NUM*ID_WIDTH-1:0]    s_wr_did            ,
    
    input   [S_NUM-1:0]             s_rd_ready          ,
    input   [S_NUM*ADDR_WIDTH-1:0]  s_rd_addr           ,
    input   [S_NUM*ID_WIDTH-1:0]    s_rd_did            ,
    output  [S_NUM-1:0]             s_rd_valid          ,
    output  [S_NUM*DATA_WIDTH-1:0]  s_rd_data           ,
    //to Slave
    input   [M_NUM-1:0]             m_wr_ready          ,
    output  [M_NUM-1:0]             m_wr_valid          ,
    output  [M_NUM-1:0]             m_wr_last           ,
    output  [M_NUM*DATA_WIDTH-1:0]  m_wr_data           ,
    output  [M_NUM*ADDR_WIDTH-1:0]  m_wr_addr           ,
    input   [M_NUM*ID_WIDTH-1:0]    m_wr_sid            ,

    output  [M_NUM-1:0]             m_rd_ready          ,
    output  [M_NUM*ADDR_WIDTH-1:0]  m_rd_addr           ,
    input   [M_NUM-1:0]             m_rd_valid          ,
    input   [M_NUM*DATA_WIDTH-1:0]  m_rd_data           ,
    input   [M_NUM*ID_WIDTH-1:0]    m_rd_sid   
);
local_wr_bus_lite#(
    .DATA_WIDTH                     (DATA_WIDTH         ),
    .ADDR_WIDTH                     (ADDR_WIDTH         ),
    .ID_WIDTH                       (ID_WIDTH           ),
    .S_NUM                          (S_NUM              ),
    .M_NUM                          (M_NUM              ),
    .AHEAD                          (AHEAD                  )//非必要不关注
)local_wr_bus_lite(          
    .i_clk                          (i_clk              ),//input                           
    .i_rst                          (i_rst              ),//input                           
    .s_wr_ready                     (s_wr_ready         ),//output  [S_NUM-1:0]             
    .s_wr_valid                     (s_wr_valid         ),//input   [S_NUM-1:0]             
    .s_wr_last                      (s_wr_last          ),//input   [S_NUM-1:0]             
    .s_wr_data                      (s_wr_data          ),//input   [S_NUM*DATA_WIDTH-1:0]  
    .s_wr_addr                      (s_wr_addr          ),//input   [S_NUM*ADDR_WIDTH-1:0]  
    .s_wr_did                       (s_wr_did           ),//input   [S_NUM*ID_WIDTH-1:0]    
    .m_wr_ready                     (m_wr_ready         ),//input   [M_NUM-1:0]             
    .m_wr_valid                     (m_wr_valid         ),//output  [M_NUM-1:0]             
    .m_wr_last                      (m_wr_last          ),//output  [M_NUM-1:0]             
    .m_wr_data                      (m_wr_data          ),//output  [M_NUM*DATA_WIDTH-1:0]  
    .m_wr_addr                      (m_wr_addr          ),//output  [M_NUM*ADDR_WIDTH-1:0]  
    .m_wr_sid                       (m_wr_sid           ) //input   [M_NUM*ID_WIDTH-1:0]     
);          
local_rd_bus_lite#(          
    .DATA_WIDTH                     (DATA_WIDTH         ),
    .ADDR_WIDTH                     (ADDR_WIDTH         ),
    .ID_WIDTH                       (ID_WIDTH           ),
    .S_NUM                          (S_NUM              ),
    .M_NUM                          (M_NUM              )
)local_rd_bus_lite(                  
    .i_clk                          (i_clk              ),//input                           
    .i_rst                          (i_rst              ),//input                           
    .s_rd_ready                     (s_rd_ready         ),//input   [S_NUM-1:0]             
    .s_rd_addr                      (s_rd_addr          ),//input   [S_NUM*ADDR_WIDTH-1:0]  
    .s_rd_did                       (s_rd_did           ),//input   [S_NUM*ID_WIDTH-1:0]    
    .s_rd_valid                     (s_rd_valid         ),//output  [S_NUM-1:0]             
    .s_rd_data                      (s_rd_data          ),//output  [S_NUM*DATA_WIDTH-1:0]  
    .m_rd_ready                     (m_rd_ready         ),//output  [M_NUM-1:0]             
    .m_rd_addr                      (m_rd_addr          ),//output  [M_NUM*ADDR_WIDTH-1:0]  
    .m_rd_valid                     (m_rd_valid         ),//input   [M_NUM-1:0]             
    .m_rd_data                      (m_rd_data          ),//input   [M_NUM*DATA_WIDTH-1:0]  
    .m_rd_sid                       (m_rd_sid           ) //input   [M_NUM*ID_WIDTH-1:0]             
);

endmodule

local_wr_bus_lite

module local_wr_bus_lite#(
    parameter   DATA_WIDTH          =   32              ,
    parameter   ADDR_WIDTH          =   24              ,
    parameter   ID_WIDTH            =   8               ,
    parameter   S_NUM               =   1               ,
    parameter   M_NUM               =   16              ,
    parameter   AHEAD               =   {(S_NUM > M_NUM ? S_NUM : M_NUM){1'b1}}//1 : valid is first ; 0 : ready is first
)(
    input                           i_clk               ,
    input                           i_rst               ,

    output  [S_NUM-1:0]             s_wr_ready          ,
    input   [S_NUM-1:0]             s_wr_valid          ,
    input   [S_NUM-1:0]             s_wr_last           ,
    input   [S_NUM*DATA_WIDTH-1:0]  s_wr_data           ,
    input   [S_NUM*ADDR_WIDTH-1:0]  s_wr_addr           ,
    input   [S_NUM*ID_WIDTH-1:0]    s_wr_did            ,
    
    input   [M_NUM-1:0]             m_wr_ready          ,
    output  [M_NUM-1:0]             m_wr_valid          ,
    output  [M_NUM-1:0]             m_wr_last           ,
    output  [M_NUM*DATA_WIDTH-1:0]  m_wr_data           ,
    output  [M_NUM*ADDR_WIDTH-1:0]  m_wr_addr           ,
    input   [M_NUM*ID_WIDTH-1:0]    m_wr_sid                      
);
//-----------------------------------------------------------------
wire        [S_NUM-1:0]             comp_S_did_miss     ;
wire        [S_NUM*M_NUM-1:0]       comp_S              ;
wire        [S_NUM*M_NUM-1:0]       comp_M              ;

wire        [M_NUM-1:0]             s_comp[S_NUM-1:0]   ;
wire        [9:0]                   s_hit_mem[S_NUM-1:0];
wire        [S_NUM-1:0]             s_req               ;
reg         [S_NUM-1:0]             weight              ;
wire        [9:0]                   s_hit               ;
reg         [3:0]                   weight_clear        ;

reg         [S_NUM-1:0]             s_sel               ;
reg         [M_NUM-1:0]             m_sel               ;

wire                                s_valid             ;
wire                                s_last              ;
wire                                m_ready             ;
wire        [ADDR_WIDTH-1:0]        s_addr              ;
wire        [DATA_WIDTH-1:0]        s_data              ;

reg         [15:0]                  time_cnt            ;
wire                                time_out            ;
//-----------------------------------------------------------------
id_wr_compare#(
    .ID_WIDTH               (ID_WIDTH               ),
    .S_NUM                  (S_NUM                  ),
    .M_NUM                  (M_NUM                  )
    
)id_wr_compare(
    .i_clk                  (i_clk                  ),
    .i_rst                  (i_rst                  ),
    .s_wr_valid             (s_wr_valid | ~AHEAD    ),
    .s_wr_did               (s_wr_did               ),
    .m_wr_ready             (m_wr_ready | AHEAD     ),
    .m_wr_sid               (m_wr_sid               ),
    .comp_S_did_miss        (comp_S_did_miss        ),
    .comp_S                 (comp_S                 ),
    .comp_M                 (comp_M                 ));
//-----------------------------------------------------------------
//-----------------------------------------------------------------
wire[S_NUM-1:0]  s_sel_p    =   s_req & (~s_req + 1);//Select the lowest bit of 1 and  the other bits at 0
always@(posedge i_clk or posedge i_rst)begin
    if(i_rst)begin
        s_sel   <=  'd0;
        m_sel   <=  'd0;
    end else if(s_valid && s_last && m_ready)begin
        s_sel   <=  'd0;
        m_sel   <=  'd0;
    end else if(|s_sel == 1'b0)begin
        s_sel   <=  s_sel_p;
        m_sel   <=  s_comp[s_hit];
    end else begin
        s_sel   <=  s_sel & (~weight);
    end
end
//-----------------------------------------------------------------
genvar  s;generate for(s=0;s<S_NUM;s=s+1)begin: SC//receive channel
    assign  s_comp[s]   =   comp_S[(s+1)*M_NUM-1:s*M_NUM];
    
    assign  s_req [s]   =   (|s_comp[s]) & (~weight[s]);

    assign  s_hit_mem[s]=   s[9:0] & {10{s_sel_p[s]}};
    //
    always@(posedge i_clk or posedge i_rst)begin
        if(i_rst)
            weight[s]  <=  1'b0;
        else if(&weight_clear)
            weight[s]  <=  1'b0;
        else if((s_wr_ready[s] && s_wr_valid[s] && s_wr_last[s]) || (time_out && s_sel[s]))
            weight[s]  <=  1'b1;
    end
    //
end endgenerate
//-----------------------------------------------------------------
genvar  i,j;generate for(i=0;i<10;i=i+1)begin: hit_S_channel
    wire    [S_NUM-1:0] hit_sc;
    for(j=0;j<S_NUM;j=j+1)begin
        assign  hit_sc[j]  =   s_hit_mem[j][i];
    end
    assign  s_hit[i]  =   |hit_sc;
end endgenerate
//-----------------------------------------------------------------
always@(posedge i_clk or posedge i_rst)begin
    if(i_rst)
        weight_clear    <=  4'd0;
    else if((|weight == 1'b0) || (s_valid && m_ready))
        weight_clear    <=  4'd0;
    else if(&weight)
        weight_clear    <=  4'hf;
    else if(~(s_valid && m_ready))
        weight_clear    <=  {weight_clear,(|s_req == 1'b0)};
end
//-----------------------------------------------------------------
always@(posedge i_clk or posedge i_rst)begin
    if(i_rst)
        time_cnt        <=  16'd0;
    else if(time_out)
        time_cnt        <=  16'd0;
    else if(|s_sel && (m_wr_ready & m_wr_valid == {M_NUM{1'b0}}))
        time_cnt        <=  16'd1 + time_cnt;
    else
        time_cnt        <=  16'd0;
end
assign  time_out    =   time_cnt[15];
//-----------------------------------------------------------------
assign  s_valid     =   |(s_wr_valid & s_sel) ;
assign  s_last      =   |(s_wr_last  & s_sel) ;
assign  m_ready     =   |(m_wr_ready & m_sel) ;

genvar  adw,ads;generate for(adw=0;adw<ADDR_WIDTH;adw=adw+1)begin: addr_S_channel
    wire    [S_NUM-1:0] addr_sc;
    for(ads=0;ads<S_NUM;ads=ads+1)begin
        assign  addr_sc[ads]  =   s_wr_addr[ads*ADDR_WIDTH+adw] & s_sel[ads];
    end
    assign  s_addr[adw]  =   |addr_sc;
end endgenerate

genvar  daw,das;generate for(daw=0;daw<DATA_WIDTH;daw=daw+1)begin: data_S_channel
    wire    [S_NUM-1:0] data_sc;
    for(das=0;das<S_NUM;das=das+1)begin
        assign  data_sc[das]  =   s_wr_data[das*DATA_WIDTH+daw] & s_sel[das];
    end
    assign  s_data[daw]  =   |data_sc;
end endgenerate
//-----------------------------------------------------------------
assign  m_wr_valid    =   m_sel & {M_NUM{s_valid}};
assign  m_wr_last     =   m_sel & {M_NUM{s_last}};
assign  m_wr_data     =   {M_NUM{s_data}};
assign  m_wr_addr     =   {M_NUM{s_addr}};

assign  s_wr_ready    =   s_sel & {S_NUM{m_ready}} | (comp_S_did_miss & s_wr_valid);

endmodule

//========================================================================================================
module id_wr_compare#(
    parameter   ID_WIDTH            =   8               ,
    parameter   S_NUM               =   16              ,
    parameter   M_NUM               =   16              

    
)(
    input                           i_clk               ,
    input                           i_rst               ,

    input   [S_NUM-1:0]             s_wr_valid          ,
    input   [S_NUM*ID_WIDTH-1:0]    s_wr_did            ,
    input   [M_NUM-1:0]             m_wr_ready          ,
    input   [M_NUM*ID_WIDTH-1:0]    m_wr_sid            ,

    output  [S_NUM-1:0]             comp_S_did_miss     ,
    output  [S_NUM*M_NUM-1:0]       comp_S              ,
    output  [S_NUM*M_NUM-1:0]       comp_M
    );
wire        [S_NUM-1:0]             S_valid             ;
wire        [ID_WIDTH-1:0]          S_did[S_NUM-1:0]    ;
wire        [M_NUM-1:0]             S_comp[S_NUM-1:0]   ;
wire        [M_NUM-1:0]             S_comp_did_exist[S_NUM-1:0]   ;

wire        [M_NUM-1:0]             M_ready             ;
wire        [ID_WIDTH-1:0]          M_sid[M_NUM-1:0]    ;
wire        [S_NUM-1:0]             M_comp[M_NUM-1:0]   ;

genvar s ;generate for(s=0;s<S_NUM;s=s+1)begin
    assign  S_valid[s]  =   s_wr_valid[s];
    assign  S_did[s]    =   s_wr_did[(s+1)*ID_WIDTH-1:s*ID_WIDTH];
    assign  comp_S_did_miss[s]  =   ~(|S_comp_did_exist[s]);
    assign  comp_S[(s+1)*M_NUM-1:s*M_NUM]   =   S_comp[s];
end endgenerate

genvar m ;generate for(m=0;m<M_NUM;m=m+1)begin
    assign  M_ready[m]  =   m_wr_ready[m];
    assign  M_sid[m]    =   m_wr_sid[(m+1)*ID_WIDTH-1:m*ID_WIDTH];
    assign  comp_M[(m+1)*S_NUM-1:m*S_NUM]   =   M_comp[m];
end endgenerate

genvar i,j;generate for(i=0;i<S_NUM;i=i+1)begin
    for(j=0;j<M_NUM;j=j+1)begin
        assign  S_comp[i][j]    =   (S_did[i] == M_sid[j]) && (S_valid[i] == M_ready[j]);
        assign  M_comp[j][i]    =   S_comp[i][j];
        assign  S_comp_did_exist[i][j] = (S_did[i] == M_sid[j]);
    end
end endgenerate



endmodule

local_rd_bus_lite

module local_rd_bus_lite#(
    parameter   DATA_WIDTH          =   32              ,
    parameter   ADDR_WIDTH          =   24              ,
    parameter   ID_WIDTH            =   8               ,
    parameter   S_NUM               =   1               ,
    parameter   M_NUM               =   16              
)(
    input                           i_clk               ,
    input                           i_rst               ,

    input   [S_NUM-1:0]             s_rd_ready          ,
    input   [S_NUM*ADDR_WIDTH-1:0]  s_rd_addr           ,
    input   [S_NUM*ID_WIDTH-1:0]    s_rd_did            ,
    output  [S_NUM-1:0]             s_rd_valid          ,
    output  [S_NUM*DATA_WIDTH-1:0]  s_rd_data           ,
    
    output  [M_NUM-1:0]             m_rd_ready          ,
    output  [M_NUM*ADDR_WIDTH-1:0]  m_rd_addr           ,
    input   [M_NUM-1:0]             m_rd_valid          ,
    input   [M_NUM*DATA_WIDTH-1:0]  m_rd_data           ,
    input   [M_NUM*ID_WIDTH-1:0]    m_rd_sid                      
);
//-----------------------------------------------------------------
wire        [S_NUM-1:0]             comp_S_did_miss     ;
wire        [S_NUM*M_NUM-1:0]       comp_S              ;
wire        [S_NUM*M_NUM-1:0]       comp_M              ;

wire        [M_NUM-1:0]             s_comp[S_NUM-1:0]   ;
wire        [9:0]                   s_hit_mem[S_NUM-1:0];
wire        [S_NUM-1:0]             s_req               ;
reg         [S_NUM-1:0]             weight              ;
wire        [9:0]                   s_hit               ;
reg         [3:0]                   weight_clear        ;

reg         [S_NUM-1:0]             s_sel               ;
reg         [M_NUM-1:0]             m_sel               ;

wire                                s_ready             ;
wire        [ADDR_WIDTH-1:0]        s_addr              ;

wire                                m_valid             ;
wire        [DATA_WIDTH-1:0]        m_data              ;

reg         [15:0]                  time_cnt            ;
wire                                time_out            ;
reg         [S_NUM-1:0]             s_rd_ready_1d       ;
//-----------------------------------------------------------------
always@(posedge i_clk)  s_rd_ready_1d <= s_rd_ready;
id_rd_compare#(
    .ID_WIDTH               (ID_WIDTH               ),
    .S_NUM                  (S_NUM                  ),
    .M_NUM                  (M_NUM                  )
    
)id_rd_compare(
    .i_clk                  (i_clk                  ),
    .i_rst                  (i_rst                  ),
    .s_rd_valid             (s_rd_ready             ),
    .s_rd_did               (s_rd_did               ),
    .m_rd_ready             ({M_NUM{1'b1}}          ),
    .m_rd_sid               (m_rd_sid               ),
    .comp_S_did_miss        (comp_S_did_miss        ),
    .comp_S                 (comp_S                 ),
    .comp_M                 (comp_M                 ));
//-----------------------------------------------------------------
wire[S_NUM-1:0]  s_sel_p    =   s_req & (~s_req + 1);//Select the lowest bit of 1 and  the other bits at 0
always@(posedge i_clk or posedge i_rst)begin
    if(i_rst)begin
        s_sel   <=  'd0;
        m_sel   <=  'd0;
    end else if(|(~s_rd_ready & s_rd_ready_1d & s_sel))begin
        s_sel   <=  'd0;
        m_sel   <=  'd0;
    end else if(|s_sel == 1'b0)begin
        s_sel   <=  s_sel_p;
        m_sel   <=  s_comp[s_hit];
    end else begin
        s_sel   <=  s_sel & (~weight);
    end
end
//-----------------------------------------------------------------
genvar  s;generate for(s=0;s<S_NUM;s=s+1)begin: SC//receive channel
    assign  s_comp[s]   =   comp_S[(s+1)*M_NUM-1:s*M_NUM];
    
    assign  s_req [s]   =   (|s_comp[s]) & (~weight[s]);

    assign  s_hit_mem[s]=   s[9:0] & {10{s_sel_p[s]}};
    //
    always@(posedge i_clk or posedge i_rst)begin
        if(i_rst)
            weight[s]  <=  1'b0;
        else if(&weight_clear)
            weight[s]  <=  1'b0;
        else if((~s_rd_ready[s] && s_rd_ready_1d[s] && s_sel[s]) || (time_out && s_sel[s]))
            weight[s]  <=  1'b1;
    end
    //
end endgenerate
//-----------------------------------------------------------------
genvar  i,j;generate for(i=0;i<10;i=i+1)begin: hit_S_channel
    wire    [S_NUM-1:0] hit_sc;
    for(j=0;j<S_NUM;j=j+1)begin
        assign  hit_sc[j]  =   s_hit_mem[j][i];
    end
    assign  s_hit[i]  =   |hit_sc;
end endgenerate
//-----------------------------------------------------------------
always@(posedge i_clk or posedge i_rst)begin
    if(i_rst)
        weight_clear    <=  4'd0;
    else if((|weight == 1'b0) || (s_ready && m_valid))
        weight_clear    <=  4'd0;
    else if(&weight)
        weight_clear    <=  4'hf;
    else if(~(s_ready && m_valid))
        weight_clear    <=  {weight_clear,(|s_req == 1'b0)};
end
//-----------------------------------------------------------------
always@(posedge i_clk or posedge i_rst)begin
    if(i_rst)
        time_cnt        <=  16'd0;
    else if(time_out)
        time_cnt        <=  16'd0;
    else if(|s_sel && (m_rd_valid & m_rd_ready == {M_NUM{1'b0}}))
        time_cnt        <=  16'd1 + time_cnt;
    else
        time_cnt        <=  16'd0;
end
assign  time_out    =   time_cnt[15];
//-----------------------------------------------------------------
assign  s_ready     =   |(s_rd_ready & s_sel) ;
assign  m_valid     =   |(m_rd_valid & m_sel) ;

genvar  adw,ads;generate for(adw=0;adw<ADDR_WIDTH;adw=adw+1)begin: addr_S_channel
    wire    [S_NUM-1:0] addr_sc;
    for(ads=0;ads<S_NUM;ads=ads+1)begin
        assign  addr_sc[ads]  =   s_rd_addr[ads*ADDR_WIDTH+adw] & s_sel[ads];
    end
    assign  s_addr[adw]  =   |addr_sc;
end endgenerate

genvar  daw,das;generate for(daw=0;daw<DATA_WIDTH;daw=daw+1)begin: data_M_channel
    wire    [M_NUM-1:0] data_sc;
    for(das=0;das<M_NUM;das=das+1)begin
        assign  data_sc[das]  =   m_rd_data[das*DATA_WIDTH+daw] & m_sel[das];
    end
    assign  m_data[daw]  =   |data_sc;
end endgenerate
//-----------------------------------------------------------------
assign  m_rd_ready    =   m_sel & {M_NUM{s_rd_ready}};
assign  m_rd_addr     =   {M_NUM{s_rd_addr}};

assign  s_rd_valid    =   (s_sel & {S_NUM{m_valid}}) | (comp_S_did_miss & m_rd_ready);
assign  s_rd_data     =   {S_NUM{m_data}};

endmodule

//========================================================================================================
module id_rd_compare#(
    parameter   ID_WIDTH            =   8               ,
    parameter   S_NUM               =   16              ,
    parameter   M_NUM               =   16              

    
)(
    input                           i_clk               ,
    input                           i_rst               ,

    input   [S_NUM-1:0]             s_rd_valid          ,
    input   [S_NUM*ID_WIDTH-1:0]    s_rd_did            ,
    input   [M_NUM-1:0]             m_rd_ready          ,
    input   [M_NUM*ID_WIDTH-1:0]    m_rd_sid            ,

    output  [S_NUM-1:0]             comp_S_did_miss     ,
    output  [S_NUM*M_NUM-1:0]       comp_S              ,
    output  [S_NUM*M_NUM-1:0]       comp_M
    );
wire        [S_NUM-1:0]             S_valid             ;
wire        [ID_WIDTH-1:0]          S_did[S_NUM-1:0]    ;
wire        [M_NUM-1:0]             S_comp[S_NUM-1:0]   ;
wire        [M_NUM-1:0]             S_comp_did_exist[S_NUM-1:0]   ;

wire        [M_NUM-1:0]             M_ready             ;
wire        [ID_WIDTH-1:0]          M_sid[M_NUM-1:0]    ;
wire        [S_NUM-1:0]             M_comp[M_NUM-1:0]   ;

genvar s ;generate for(s=0;s<S_NUM;s=s+1)begin
    assign  S_valid[s]  =   s_rd_valid[s];
    assign  S_did[s]    =   s_rd_did[(s+1)*ID_WIDTH-1:s*ID_WIDTH];
    assign  comp_S_did_miss[s]  =   ~(|S_comp_did_exist[s]);
    assign  comp_S[(s+1)*M_NUM-1:s*M_NUM]   =   S_comp[s];
end endgenerate

genvar m ;generate for(m=0;m<M_NUM;m=m+1)begin
    assign  M_ready[m]  =   m_rd_ready[m];
    assign  M_sid[m]    =   m_rd_sid[(m+1)*ID_WIDTH-1:m*ID_WIDTH];
    assign  comp_M[(m+1)*S_NUM-1:m*S_NUM]   =   M_comp[m];
end endgenerate

genvar i,j;generate for(i=0;i<S_NUM;i=i+1)begin
    for(j=0;j<M_NUM;j=j+1)begin
        assign  S_comp[i][j]    =   (S_did[i] == M_sid[j]) && (S_valid[i] == M_ready[j]);
        assign  M_comp[j][i]    =   S_comp[i][j];
        assign  S_comp_did_exist[i][j] = (S_did[i] == M_sid[j]);
    end
end endgenerate



endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值