我想实现一个多路复用器,给定一个控制信号(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']
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
答案 0 :(得分:3)
这将在您的情况下生成一个闩锁。您不会在这里介绍所有可能的情况。
dispatch
尝试此操作。将默认案例提前移动:
for(i=0;i<TOTAL_REGS;i++)begin
if(addr_i==i) begin
reg_data_out =slv_reg[i];
end
end