In the following code: First, I am loading ROM with data and weight at given address. In the same clock I am doing multiplication of data and weight. Finally, I am extending the number of bits from 16-bit to 23-bit. The code compiles without errors but has warnings. I am unable to solve these warnings.
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 ####################
WARNING 646 - Signal "a" is assigned but never used. This unconnected signal will be trimmed during the optimization process.
WARNING 1710 - "FF/Latch a4/extended_15" (without init value) has a constant value of 0 in block main_module. This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other ""FF/Latch trimming"", FF/Latch ""a4/extended_14"" (without init value) has a constant value of 0 in block "main_module". This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch ""a4/extended_13"" (without init value) has a constant value of 0 in block ""main_module"". This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch ""a4/extended_12"" (without init value) has a constant value of 0 in block ""main_module"". This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch ""a4/extended_11"" (without init value) has a constant value of 0 in block ""main_module"". This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch ""a4/extended_10"" (without init value) has a constant value of 0 in block ""main_module"". This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch ""a4/extended_0"" (without init value) has a constant value of 0 in block ""main_module"". This FF/Latch will be trimmed during the optimization process.
warning--1 says you didn't use constant "a" variable but while doing multiplication I took as an temporary register but remaining errors I don't understand what they really going to tell...
Please help explain these warnings.
The warnings are caused by the synthesizer informing you that the generated netlist does not match your RTL but is functionally equivalent. For beginner FPGA designers the warning can somewhat be ignored, but they should learn how to resolve the warnings. IC designers almost always resolve the warning because it can make ECOs even more difficult, among other issues. The optimizer in your synthesizer tool is recognizing that bits
extended[0]
andextended[15:10]
have a zero percent change of having a value other than0
. It also decided thata
is not necessary.extended[0]
can only be0
becausedata[0]
is only assigned to an even number. Any whole number multiplied by an even number is always even, thus the LSB will always be zero. The logic and flop/latch used to calculate this bit can safely be replaced with a0
driver.Similar optimization is happening for bits
extended[15:10]
. The largest valueextended
can have is16'b0000_0001_1110_0000
;8'b0000_1100
(data) times8'b0010_1000
(weight) when the clockedaddr==3'b110
. Within the available values ofdata
andweight
there is no possible combination that any bit greater than 9 can be anything except0
. Like bit 0, the synthesizer decided to save space and improve performance rather than follow your code verbatim. Most likely somewhere in the synthesis log there are warnings that bitsextended[22:16]
are also being trimmed during the optimization process.The warning for
a
is not because it is a temporary variable. The optimizer recognizesextended
can only be one of eight possible values. The values ofdata
andweight
values are derived from look-up tables that use the same index pointer (addr
). Once again, it takes less logic and better performance to hard code the 8 values into another look-up table then the actual multiplication logic. With the multiplier logic no longer necessary,a
becomes useless and is removed.Try refactoring your RTL. Also make sure names of modules and nets make sense; ex
top_module
tomultiplier_8bit
andram_*
torom_*
. Consolidate redundant logic and more concise functional logic. You can ignore the warnings if you just want that mostly works. If you want to become a good logic designer, then you should try to resolve the warnings.Your basic problem is probably the
p=p+a
intop_module
. This doesn't make sense; try to draw the schematic. This is a combinatorial path with the output of an adder fed back to its input. Get rid of it, and just add together the , depending on the relevant bit ofy
. This may be enough to get you going.EDIT
Your code is unlikely to be (correctly) synthesisable (by any sane synthesiser, anyway). Consider this:
This is combinatorial code. You are asking the synthesiser to unroll your
i
loop. Every timex
ory
changes, you want the synthesiser to evaluate all 8 loop iterations, shiftinga
, and accumulating top
. Synthesisers are normally pretty good at loop unrolling, but this one is pushing it. Get rid of the loop, whether or not you think XST understands it; it's just bad practice, and is probably confusing XST. Draw a schematic on paper. All you're doing is shiftinga
: you've got one unmodifieda
, and 7 instances wherea
is shifted by 1 to 7 bits. You need an adder which adds together all 8 busses, but you only add in bus i if the corresponding bit ofy
is set. In other words, each input to the adder has a multiplexer on it; one input is held to zero, the other is your shifteda
. You'll need to write the code yourself. This is how you do hardware design: break everything down into basic units - multiplexers, shifters, adders, whatever, and wire them togehter. Don't write behavioural code that your synthesiser has to try to work out for you; that's software, not hardware.Greg may be right in that your actual circuit can be simplified according to your actual input conditions, and that this circuit is eventually unused anyway; it's not a 5-minute job to confirm that, and it's pointless anyway. You're trying to write a multiplier, and your input conditions will change, and you need to get the code right. XST may, or may not, be able to work out that in any particular situation it can simplify the logic, but you have to fix your input code first.
You have other issues. Don't assign X's to your variables as Don't Cares. This is very bad practice, and will go wrong. Read Mike Turpin's paper, among others. In short, never use X's unless you know exactly what you're doing. Use non-blocking assignments in the
x
/y
always block. There may be other issues, which aren't obvious on a very quick read-through.