如何在参数设计中使用组合逻辑分配输出

时间:2019-08-27 08:19:00

标签: parameters verilog system-verilog

我想实现一个多路复用器,给定一个控制信号(addr_i),将寄存器(slv_reg [i])的内容放入输出(data_o)。其中“ i”是从0到模块参数TOTAL_REGS的值。 我可以在for循环中分配slv_reg而不生成闩锁吗?

我已经写了几个简单的例子。但是,即使我的逻辑涵盖了所有可能的条件(如果缺少其他条件),它也会生成闩锁。手动执行此操作时,我可以编写else并摆脱该问题,但是使用循环时,我不知道该怎么做。

module why_latch_1 #                                                 
    (                                                                
        // Width of data bus                                         
        parameter integer DATA_WIDTH    = 32,                        
        // Number of registers                                       
        parameter integer TOTAL_REGS = 3                             
    )                                                                
    (                                                                
     input wire clk_i,                                               
     input wire rstn_i,                                              
     input wire [DATA_WIDTH-1:0] addr_i,                             
     output wire [DATA_WIDTH-1:0] data_o                             
    );                                                               
    reg [DATA_WIDTH-1:0] slv_reg [0:TOTAL_REGS-1];                   
    reg [DATA_WIDTH-1:0] reg_data_out;                               
    assign data_o = reg_data_out;                                    

    integer i;                                                       

    always @(posedge clk_i)                                          
        if (~rstn_i) begin                                           
            for (i=0; i<TOTAL_REGS; i=i+1) begin                     
                slv_reg[i]<={DATA_WIDTH{1'b0}};                      
            end                                                      
        end                                                          

    always_comb                                                      
    begin : decode                                                   
    //check if the address is out of the range of R registers        
        if (addr_i>0 && addr_i <= TOTAL_REGS) begin                  
            //this is a latch                                        
            integer i;                                               
            for(i=0;i<TOTAL_REGS;i++)begin                           
                if(addr_i==i) begin                                  
                    reg_data_out =slv_reg[i];                        
                end                                                  
            end                                                      
        end else                                                     
            reg_data_out ={DATA_WIDTH{1'b0}};                        
    end                                                              
    endmodule                                                        



module why_latch_2 #                                      
(                                                         
    // Width of data bus                                  
    parameter integer DATA_WIDTH    = 32,                 
    // Number of registers                                
    parameter integer TOTAL_REGS = 3                      
)                                                         
(                                                         
 input wire clk_i,                                        
 input wire rstn_i,                                       
 input wire [DATA_WIDTH-1:0] addr_i,                      
 output wire [DATA_WIDTH-1:0] data_o                      
);                                                        
reg [DATA_WIDTH-1:0] slv_reg [0:TOTAL_REGS-1];            
reg [DATA_WIDTH-1:0] reg_data_out;                        
assign data_o = reg_data_out;                             

integer i;                                                

always @(posedge clk_i)                                   
    if (~rstn_i) begin                                    
        for (i=0; i<TOTAL_REGS; i=i+1) begin              
            slv_reg[i]<={DATA_WIDTH{1'b0}};               
        end                                               
    end                                                   

always_comb                                               
begin : decode                                            
//check if the address is out of the range of R registers 
    if (addr_i>0 && addr_i <= TOTAL_REGS) begin           
        //this is NOT a latch                             
        if(addr_i==0)                                     
            reg_data_out =slv_reg[0];                     
        else                                              
            if(addr_i==1)                                 
                reg_data_out =slv_reg[1];                 
            else                                          
                reg_data_out =slv_reg[2];                 
    end else                                              
        reg_data_out ={DATA_WIDTH{1'b0}};                 
end                                                       
endmodule                                                 

通过使用望远镜作为棉绒工具,我得到以下报告:

对于模块why_latch_2。就像我所期望的那样,一切都很好。

############### BuiltIn -> RuleGroup=Design Read ###############                
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ID       Rule                    Alias                   Severity    File                                                                                  Line    Wt    Message
======================================================================================
[1]      DetectTopDesignUnits    DetectTopDesignUnits    Info        ./why_latch_2.sv                                                                      1       2     Module why_latch_2 is a top level desi
gn unit
[0]      ElabSummary             ElabSummary             Info        ./why_latch_2/why_latch_2/lint/lint_rtl/spyglass_reports/SpyGlass/elab_summary.rpt    0       2     Please refer file './why_latch_2/why_l
atch_2/lint/lint_rtl/spyglass_reports/SpyGlass/elab_summary.rpt' for elab summary report
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

关于why_latch_1:

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++         
MORESIMPLE REPORT:                                                              


############### BuiltIn -> RuleGroup=Design Read ###############                
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ID       Rule                    Alias                   Severity            File                                                                                  Line    Wt      Message
======================================================================================
[1]      DetectTopDesignUnits    DetectTopDesignUnits    Info                ./why_latch_1.sv                                                                      1       2       Module why_latch_1 is a top 
level design unit
[4]      SYNTH_12608                                     SynthesisWarning    ./why_latch_1.sv                                                                      27      1000    why_latch_1 -> The logic of 
the always block mismatches with the type of Always Block(which should be "always_latch (Latch)") due to latch instance \reg_data_out_reg[0]
[0]      ElabSummary             ElabSummary             Info                ./why_latch_1/why_latch_1/lint/lint_rtl/spyglass_reports/SpyGlass/elab_summary.rpt    0       2       Please refer file './why_lat
ch_1/why_latch_1/lint/lint_rtl/spyglass_reports/SpyGlass/elab_summary.rpt' for elab summary report
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


############### Non-BuiltIn -> Goal=lint/lint_rtl ###############               
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ID       Rule          Alias                 Severity    File                Line    Wt    Message
======================================================================================
[7]      InferLatch    (OpenMORE 5.5.2.1)    Error       ./why_latch_1.sv    40      5     Latch inferred for signal 'reg_data_out[31:0]' in module 'why_latch_1'
[2]      W415a                               Warning     ./why_latch_1.sv    35      5     Signal reg_data_out is being assigned multiple times ( assignment within same for-loop ) in same always block [Hiera
rchy: ':why_latch_1']
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

1 个答案:

答案 0 :(得分:3)

这将在您的情况下生成一个闩锁。您不会在这里介绍所有可能的情况。

dispatch

尝试此操作。将默认案例提前移动:

       for(i=0;i<TOTAL_REGS;i++)begin                           
            if(addr_i==i) begin                                  
                reg_data_out =slv_reg[i];                        
            end                                                  
        end