在下面的代码中:首先,我在给定地址的数据和权重加载ROM。在同一个时钟中,我正在进行数据和权重的乘法运算。最后,我将位数从16位扩展到23位。代码编译没有错误但有警告。我无法解决这些警告。
module main_module(extended_out,mux_out,data,weight,clk,en,addr);
input clk,en;
input [2:0] addr;
output [7:0] data,weight;
output [15:0] mux_out;
output [22:0] extended_out;
ram_input a1 (clk, en, addr, data);
ram_weight a2 (clk, en, addr, weight);
top_module a3 (mux_out,data,weight);
SignExtender a4 (clk,mux_out,extended_out);
endmodule
################### MODULE 1 ####################### #################
module ram_input (clk, en, addr, data);
input clk;
input en;
input [2:0] addr;
output reg [7:0] data;
reg [2:0] raddr;
always @(posedge clk)
begin
if (en)
raddr <= addr;
end
always @(raddr,en)
begin
if (en)
begin
case(raddr)
3'b000: data = 8'b0000_0010;
3'b001: data = 8'b0000_0110;
3'b010: data = 8'b0000_1110;
3'b011: data = 8'b0000_0010;
3'b100: data = 8'b0000_0100;
3'b101: data = 8'b0000_1010;
3'b110: data = 8'b0000_1100;
3'b111: data = 8'b0000_0000;
default: data = 8'b0000_XXXX;
endcase
end
else
data = 8'b0000_0000;
end
endmodule
####################################### MODULE 2 ### #####################
module ram_weight (clk, en, addr, weight);
input clk;
input en;
input [2:0] addr;
output reg [7:0] weight;
reg [2:0] raddr;
always @(posedge clk)
begin
if (en)
raddr <= addr;
end
always @(raddr,en)
begin
if (en)
begin
case(raddr)
3'b000: weight = 8'b0000_1000;
3'b001: weight = 8'b0000_1010;
3'b010: weight = 8'b0001_1101;
3'b011: weight = 8'b0001_0100;
3'b100: weight = 8'b0000_0111;
3'b101: weight = 8'b0001_0010;
3'b110: weight = 8'b0010_1000;
3'b111: weight = 8'b0011_1111;
default: weight = 8'b0000_XXXX;
endcase
end
else
weight = 8'b0000_0000;
end
endmodule
############################ 33 MODULE - 3 ########### ##########
module top_module(p,x,y);
output [15:0]p;
input [7:0]x,y;
reg [15:0]p;
reg [15:0]a;
integer i;
always @(x , y)
begin
a=x;
p=0;
for(i=0;i<8;i=i+1)
begin
if(y[i])
p=p+a;
a=a<<1;
end
end
endmodule
############################## MOdule ---- 4 ######## #####################
module SignExtender( clk, extend, extended );
input[15:0] extend;
input clk;
output[22:0] extended;
reg[22:0] extended;
wire [15:0] extend;
always @( posedge clk)
begin
extended[22:0] <= { {7{extend[15]}}, extend[15:0] };
end
endmodule
############################### ERROR ############ ########
警告646 - 已分配信号“a”但从未使用过。在优化过程中将修剪此未连接的信号。
警告1710 - “FF / Latch a4 / extended_15”(不带初始值)在块main_module中的常量值为0。在优化过程中将修整此FF / Latch。
警告:Xst:1895 - 由于其他“”FF / Latch修整“”,FF / Latch“”a4 / extended_14“”(没有初始值)在块“main_module”中具有常量值0。在优化过程中将修整此FF / Latch。
警告:Xst:1895 - 由于其他FF / Latch微调,FF / Latch“”a4 / extended_13“”(没有初始值)在块“”main_module“”中的常量值为0。在优化过程中将修整此FF / Latch。
警告:Xst:1895 - 由于其他FF / Latch修整,FF / Latch“”a4 / extended_12“”(没有初始值)在块“”main_module“”中具有常量值0。在优化过程中将修整此FF / Latch。
警告:Xst:1895 - 由于其他FF / Latch修整,FF / Latch“”a4 / extended_11“”(无初始值)在块“”main_module“”中的常量值为0。在优化过程中将修整此FF / Latch。
警告:Xst:1895 - 由于其他FF / Latch微调,FF / Latch“”a4 / extended_10“”(无初始值)在块“”main_module“”中的常量值为0。在优化过程中将修整此FF / Latch。
警告:Xst:1895 - 由于其他FF / Latch微调,FF / Latch“”a4 / extended_0“”(没有初始值)在块“”main_module“”中的常量值为0。在优化过程中将修整此FF / Latch。
警告 - 1表示你没有使用常量“a”变量但是在进行乘法时我把它作为一个临时寄存器但是仍然存在错误我不明白他们真正要说的是什么......
请帮助解释这些警告。
答案 0 :(得分:2)
您的基本问题可能是p=p+a
中的top_module
。这没有意义;尝试绘制原理图。这是一个组合路径,加法器的输出反馈到其输入。摆脱它,只需将加在一起,具体取决于y
的相关位。这可能足以让你前进。
修改强>
您的代码不太可能(正确)合成(无论如何,通过任何合理的合成器)。考虑一下:
always @(x , y)
begin
a=x;
p=0;
for(i=0;i<8;i=i+1)
begin
if(y[i])
p=p+a;
a=a<<1;
end
end
这是组合代码。您要求合成器展开您的i
循环。每次x
或y
更改时,您都希望合成器评估所有8个循环迭代,转移a
,并累积到p
。合成器通常非常擅长循环展开,但这个推动它。摆脱循环,无论你是否认为XST理解它;这只是不好的做法,可能会让XST感到困惑。在纸上画一个原理图。您所做的只是转移a
:您有一个未经修改的a
,以及7个a
移位1到7位的实例。你需要一个加法器,它将所有8个总线加在一起,但如果设置了y
的相应位,你只需添加总线 i 。换句话说,加法器的每个输入都有一个多路复用器;一个输入保持为零,另一个输入保持为a
。你需要自己编写代码。这就是你如何进行硬件设计:将所有内容分解为基本单元 - 多路复用器,移位器,加法器等等,并将它们连接起来。不要编写合成器必须尝试为您解决的行为代码;那是软件,而不是硬件。
Greg可能是正确的,因为您的实际电路可以根据您的实际输入条件进行简化,并且该电路最终还是未被使用;确认这一点并不是一个5分钟的工作,无论如何它都是毫无意义的。你正试图写一个乘数,你的输入条件会改变,你需要正确的代码。 XST可能会或可能不会解决在任何特定情况下它可以简化逻辑,但您必须首先修复输入代码。
您还有其他问题。不要将X分配给您的变量,如不关心。这是非常糟糕的做法,并且会出错。阅读Mike Turpin's paper等。简而言之,除非您确切知道自己在做什么,否则永远不要使用X.在x
/ y
始终阻止中使用非阻止分配。可能存在其他问题,这些问题在非常快速的阅读中并不明显。
答案 1 :(得分:1)
警告是由合成器引起的,通知您生成的网表与您的RTL不匹配,但功能相同。对于初学FPGA设计人员,警告可能会被忽略,但他们应该学习如何解决警告。 IC设计人员几乎总能解决警告问题,因为它会使ECO更加困难,尤其是其他问题。合成器工具中的优化器识别出位extended[0]
和extended[15:10]
具有除0
之外的值的零百分比变化。它还决定a
没有必要。
extended[0]
只能0
,因为data[0]
仅分配给偶数。任何整数乘以偶数始终是偶数,因此LSB将始终为零。用于计算该位的逻辑和触发器/锁存器可以安全地替换为0
驱动程序。
比特extended[15:10]
正在进行类似的优化。 extended
的最大值可以是16'b0000_0001_1110_0000
;时钟8'b0000_1100
时8'b0010_1000
(数据)乘以addr==3'b110
(权重)。在data
和weight
的可用值范围内,除了0
之外,任何大于9的位都不可能组合。与第0位一样,合成器决定节省空间并提高性能,而不是逐字地遵循您的代码。很可能在综合日志的某个地方有警告,在优化过程中也会修剪位extended[22:16]
。
a
的警告不是因为它是临时变量。优化程序识别extended
只能是八个可能值之一。 data
和weight
值的值派生自使用相同索引指针(addr
)的查找表。再一次,将8个值硬编码到另一个查找表然后实际的乘法逻辑中需要更少的逻辑和更好的性能。由于不再需要乘数逻辑,a
变得无用并被移除。
尝试refactoring您的RTL。还要确保模块和网络的名称有意义;从top_module
到multiplier_8bit
和ram_*
到rom_*
。整合冗余逻辑和更简洁的功能逻辑。如果您只是希望大多数工作,您可以忽略警告。如果你想成为一名优秀的逻辑设计师,那么你应该尝试解决警告。