Verilog error: Range must be bounded by constant expressions - verilog

I'm new to verilog and I am doing a project for my class. So here is my code:
wire [n-1:0] subcounter_of_counter;
reg [n-1:0] mask,free;
//subcounter_of_counter: dinei ena vector apo poious subcounter apoteleitai o counter(id)
always #(*) begin //command or id or mask or free or subcounter_of_counter
if (command==increment) begin
for (int i = 0; i < n; i=i+1)begin
if (i<id) begin
subcounter_of_counter[i]=1'b0;
end else if (i==id) begin
subcounter_of_counter[i]=1'b1;
end else begin
if( (|mask[id+1:i]) || (|free[id+1:i]) ) begin
subcounter_of_counter[i]=1'b0;
end else begin
subcounter_of_counter[i]=1'b1;
end
end
end
end
end
And the error says "the range must be bounded by constant expressions."
Any ideas how else I could write it to do the same operation?
Thanks a lot

What you will need to do is create a masked and shifted version of mask and free.
reg [n-1:0] mask,free,local_mask, local_free;
always #(*) begin //command or id or mask or free or subcounter_of_counter
if (command==increment) begin
local_mask = mask & ((64'b1<<id+1)-1); // clear bits above id+1
local_free = free & ((64'b1<<id+1)-1); // clear bits above id+1
for (int i = 0; i < n; i=i+1)begin
if (i<id) begin
subcounter_of_counter[i]=1'b0;
end else if (i==id) begin
subcounter_of_counter[i]=1'b1;
end else begin
if( (|local_mask) || (|local_free) ) begin
subcounter_of_counter[i]=1'b0;
end else begin
subcounter_of_counter[i]=1'b1;
end
end
end
local_mask = local_mask >> 1; // clear bits below i
local_free = local_free >> 1;
end // for
end // always
I didn't try this code, but hopefully it points you in the right direction.

Related

Resolving a warning in verilog: read after blocking assignment in same process

I've this code which is throwing some warning messages which I'm trying to resolve.
module someModuleName(...)
...
...
reg [3:0] i;
wire [3:0] onstate_count;
wire [3:0] ack_count;
reg [3:0] j;
bit switchState;
always #(*) begin :EVAL_ACK
switchState = 1'b0;
for (i = 0; i < onstate_count; i = i+1) begin
if (onStateControls[i] == 1'b1) begin
switchState = 1'b1;
end
end
for (j = 0; j < ack_count; j = j+1) begin
if (ack_expression_type[j] == 1'b0) begin
if (switchState) begin
ack[j] = ack_logic_value[j];
end else begin
ack[j] = !ack_logic_value[j];
end
end else begin
ack[j] = ack_logic_value[j];
end
end
end
endmodule
The warning mesage I'm getting is:
Warning-[SM_TPL] Transaction path loss after synthesis
In module 'someModuleName', transaction path through signal 'i' will be
lost after synthesis due to read after blocking assignment in same process.
-
Warning-[SM_TPL] Transaction path loss after synthesis
In module 'someModuleName', transaction path through signal 'switchState' will be
lost after synthesis due to read after blocking assignment in same process.
-
Warning-[SM_TPL] Transaction path loss after synthesis
In module 'someModuleName', transaction path through signal 'j' will be
lost after synthesis due to read after blocking assignment in same process.
I tried making i, j as integer and genvar but no effect, I'm new to verilog and don't know how to resolve this warning.
Any help would be highly appreciated.
Thanks.
Synthesizers require loops to static unroll.
A loop must be able to static unroll to be synthesizable.
Using a snip it from your original code:
switchState = 1'b0;
for (i = 0; i < onstate_count; i = i+1) begin // <-- onstate_count is not a compile time constant, therefore cannot static unroll
if (onStateControls[i] == 1'b1) begin
switchState = 1'b1;
end
end
The equivalent synthesizer friendly version would be:
switchState = 1'b0;
for (i = 0; i < 16; i = i+1) begin // <-- loop is static
if (i < onstate_count) begin // <-- condition check
if (onStateControls[i] == 1'b1) begin
switchState = 1'b1;
end
end
end
A similar change needs to be made to for (j = 0; j < ack_count; j = j+1). The ack also needs to be assigned a value for indexes greater than ack_count or it will infer a latches; and most FPGA synthesizers do not support latches.
Try this code. Also are onstate_count and ack_count variables constants?
module someModuleName(...)
...
...
genvar i,j;
wire [3:0] onstate_count;
wire [3:0] ack_count;
bit switchState;
generate
for (i = 0; i < onstate_count; i = i+1) begin
always #(*) begin :EVAL_ACK
switchState = 1'b0;
if (onStateControls[i] == 1'b1) begin
switchState = 1'b1;
end
end
end
endgenerate
generate
for (j = 0; j < ack_count; j = j+1) begin
always #(*) begin
if (ack_expression_type[j] == 1'b0) begin
if (switchState) begin
ack[j] = ack_logic_value[j];
end else begin
ack[j] = !ack_logic_value[j];
end
end else begin
ack[j] = ack_logic_value[j];
end
end
end
endgenerate
endmodule

Priority encoder in verilog

I am somewhat new to verilog, I tried running this code but it gives me an error:
module enc(in,out);
input [7:0] in;
output [3:0] out;
reg i;
reg [3:0] out;
always #*
begin
for (i=0;i<7;i=i+1)
begin
if ((in[i]==1) && (in[7:i+1]==0))
out = i;
else
out = 0;
end
end
endmodule
I think it complains about in[7:i+1] but i don't understand why ?
Can someone please advise..
EDIT
ok so I am reluctant to using the X due to their numerous problems.. I was thinking of modifying the code to something like this :
module enc(in,out);
input [7:0] in;
output [2:0] out;
reg i;
reg [2:0] out,temp;
always #*
begin
temp = 0;
for (i=0;i<8;i=i+1)
begin
if (in[i]==1)
temp = i;
end
out = temp;
end
endmodule
Do you think that will do the trick ? I currently don't have access to a simulator..
A priority encoder mean giving priority to a one bit if two or more bits meet the criteria. Looking at your code, it appears you wanted to give priority to a LSB while using a up counter. out is assigned in every look, so even if your could compile, the final result would be 6 or 0.
For an LSB priority encoder, first start with a default value for out and use a down counter:
module enc (
input wire [7:0] in,
output reg [2:0] out
);
integer i;
always #* begin
out = 0; // default value if 'in' is all 0's
for (i=7; i>=0; i=i-1)
if (in[i]) out = i;
end
endmodule
If you are only interested in simulation than your linear loop approach should be fine, something like
out = 0;
for (i = W - 1; i > 0; i = i - 1) begin
if (in[i] && !out)
out = i;
end
If you also care about performance, the question becomes more interesting. I once experimented with different approaches to writing parameterized priority encoders here. It turned out that Synopsys can generate efficient implementation even from the brain-dead loop above but other toolchains needed explicit generate magic. Here is an excerpt from the link:
output [WIDTH_LOG - 1:0] msb;
wire [WIDTH_LOG*WIDTH - 1:0] ors;
assign ors[WIDTH_LOG*WIDTH - 1:(WIDTH_LOG - 1)*WIDTH] = x;
genvar w, i;
integer j;
generate
for (w = WIDTH_LOG - 1; w >= 0; w = w - 1) begin
assign msb[w] = |ors[w*WIDTH + 2*(1 << w) - 1:w*WIDTH + (1 << w)];
if (w > 0) begin
assign ors[(w - 1)*WIDTH + (1 << w) - 1:(w - 1)*WIDTH] = msb[w] ? ors[w*WIDTH + 2*(1 << w) - 1:w*WIDTH + (1 << w)] : ors[w*WIDTH + (1 << w) - 1:w*WIDTH];
end
end
endgenerate
So my Edited solution worked... how silly !! I forgot to declare reg [2:0] i; and instead wrote reg i;
Thanks everybody
Hunks, I have to tell you, all your solutions are either too complex or non-synthesizable, or implement into slow multiplexors. Alexej Bolshakov at OpenCores uploaded an outstandin' parametrizable encoder on Aug 23, 2015, based on OR elements. No muxes, 100% synthesizable. His code (with my tiny formatting):
module encoder #(
parameter LINES = 16,
parameter WIDTH = $clog2(LINES)
)(
input [LINES-1:0] unitary_in,
output wor [WIDTH-1:0] binary_out
);
genvar i, j;
generate
for (i = 0; i < LINES; i = i + 1)
begin: loop_i
for (j = 0; j < WIDTH; j = j + 1)
begin: loop_j
if (i[j])
assign binary_out[j] = unitary_in[i];
end
end
endgenerate
endmodule
RTL viewer screenshot, Model-Sim screenshot
This solution divides the input into four blocks and checks for the first nonzero block. This block is further subdivided in the same way. It is reasonably efficient.
// find position of most significant 1 bit in 64 bits input
// (system verilog)
module bitscan(
input logic [63:0] in, // number input
output logic [5:0] out, // bit position output
output logic zeroout // indicates if input is zero
);
logic [63:0] m0; // intermediates
logic [15:0] m1;
logic [3:0] m2;
logic [5:0] r;
always_comb begin
m0 = in;
// choose between four 16-bit blocks
if (|m0[63:48]) begin
m1 = m0[63:48];
r[5:4] = 3;
end else if (|m0[47:32]) begin
m1 = m0[47:32];
r[5:4] = 2;
end else if (|m0[31:16]) begin
m1 = m0[31:16];
r[5:4] = 1;
end else begin
m1 = m0[15:0];
r[5:4] = 0;
end
// choose between four 4-bit blocks
if (|m1[15:12]) begin
m2 = m1[15:12];
r[3:2] = 3;
end else if (|m0[11:8]) begin
m2 = m1[11:8];
r[3:2] = 2;
end else if (|m0[7:4]) begin
m2 = m1[7:4];
r[3:2] = 1;
end else begin
m2 = m1[3:0];
r[3:2] = 0;
end
// choose between four remaining bits
if (m2[3]) r[1:0] = 3;
else if (m2[2]) r[1:0] = 2;
else if (m2[1]) r[1:0] = 1;
else r[1:0] = 0;
out = r;
zeroout = ~|m2;
end
endmodule
Here is another solution that uses slightly less resourcess:
module bitscan4 (
input logic [63:0] in,
output logic [5:0] out,
output logic zout
);
logic [63:0] m0;
logic [3:0] m1;
logic [3:0] m2;
logic [5:0] r;
always_comb begin
r = 0;
m0 = in;
if (|m0[63:48]) begin
r[5:4] = 3;
m1[3] = |m0[63:60];
m1[2] = |m0[59:56];
m1[1] = |m0[55:53];
m1[0] = |m0[51:48];
end else if (|m0[47:32]) begin
r[5:4] = 2;
m1[3] = |m0[47:44];
m1[2] = |m0[43:40];
m1[1] = |m0[39:36];
m1[0] = |m0[35:32];
end else if (|m0[31:16]) begin
r[5:4] = 1;
m1[3] = |m0[31:28];
m1[2] = |m0[27:24];
m1[1] = |m0[23:20];
m1[0] = |m0[19:16];
end else begin
r[5:4] = 0;
m1[3] = |m0[15:12];
m1[2] = |m0[11:8];
m1[1] = |m0[7:4];
m1[0] = |m0[3:0];
end
if (m1[3]) begin
r[3:2] = 3;
end else if (m1[2]) begin
r[3:2] = 2;
end else if (m1[1]) begin
r[3:2] = 1;
end else begin
r[3:2] = 0;
end
m2 = m0[{r[5:2],2'b0}+: 4];
if (m2[3]) r[1:0] = 3;
else if (m2[2]) r[1:0] = 2;
else if (m2[1]) r[1:0] = 1;
else r[1:0] = 0;
zout = ~|m2;
out = r;
end
endmodule
To be able to use variable indexes in part-slice suffixes, you must enclose the for block into a generate block, like this:
gen var i;
generate
for (i=0;i<7;i=i+1) begin :gen_slices
always #* begin
... do whatever with in[7:i+1]
end
end
The problem is that apllying this to your module, the way it's written, leads to other errors. Your rewritten module would look like this (be warned: this won't work either)
module enc (
input wire [7:0] in,
output reg [2:0] out // I believe you wanted this to be 3 bits width, not 4.
);
genvar i; //a generate block needs a genvar
generate
for (i=0;i<7;i=i+1) begin :gen_block
always #* begin
if (in[i]==1'b1 && in[7:i+1]=='b0) // now this IS allowed :)
out = i;
else
out = 3'b0;
end
end
endgenerate
endmodule
This will throw a synthesis error about out being driven from more than one source. This means that the value assigned to out comes from several sources at the same time, and that is not allowed.
This is because the for block unrolls to something like this:
always #* begin
if (in[0]==1'b1 && in[7:1]=='b0)
out = 0;
else
out = 3'b0;
end
always #* begin
if (in[1]==1'b1 && in[7:2]=='b0)
out = 1;
else
out = 3'b0;
end
always #* begin
if (in[2]==1'b1 && in[7:3]=='b0)
out = 2;
else
out = 3'b0;
end
.... and so on...
So now you have multiple combinational block (always #*) trying to set a value to out. All of them will work at the same time, and all of them will try to put a specific value to out whether the if block evaluates as true or false. Recall that the condition of each if statement is mutually exclusive with respect of the other if conditions (i.e. only one if must evaluate to true).
So a quick and dirty way to avoid this multisource situation (I'm sure there are more elegant ways to solve this) is to let out to be high impedance if the if block is not going to assign it a value. Something like this:
module enc (
input wire [7:0] in,
output reg [2:0] out // I believe you wanted this to be 3 bits width, not 4.
);
genvar i; //a generate block needs a genvar
generate
for (i=0;i<7;i=i+1) begin :gen_block
always #* begin
if (in[i]==1'b1 && in[7:i+1]=='b0) // now this IS allowed :)
out = i;
else
out = 3'bZZZ;
end
end
endgenerate
always #* begin
if (in[7]) // you missed the case in which in[7] is high
out = 3'd7;
else
out = 3'bZZZ;
end
endmodule
On the other way, if you just need a priority encoder and your design uses fixed and small widths for inputs and outputs, you may write your encoder as this:
module enc (
input wire [7:0] in,
output reg [2:0] out
);
always #* begin
casex (in)
8'b1xxxxxxx : out = 3'd7;
8'b01xxxxxx : out = 3'd6;
8'b001xxxxx : out = 3'd5;
8'b0001xxxx : out = 3'd4;
8'b00001xxx : out = 3'd3;
8'b000001xx : out = 3'd2;
8'b0000001x : out = 3'd1;
8'b00000001 : out = 3'd0;
default : out = 3'd0;
endcase
end
endmodule
(although there seems to be reasons to not to use casex in a design. Read the comment #Tim posted about it in this other question: How can I assign a "don't care" value to an output in a combinational module in Verilog )
In conclusion: I'm afraid that I have not a bullet-proof design for your requirements (if we take into account the contents of the paper Tim linked in his comment), but at least, you know now why i was unallowed inside a part-slice suffix.
On the other way, you can have half of the work done by studying this code I gave as an answer to another SO question. In this case, the module works like a priority encoder, parametrized and without casex statements, only the output is not binary, but one-hot encoded.
How to parameterize a case statement with don't cares?
out = in&(~(in-1))
gives you the one-hot results(FROM LSB->MSB where the first 1 at)

Verilog not displaying output

I have a homework problem where I'm supposed to create a module for single-precision IEEE-754 floating point multiplication. This is the module:
module prob3(a, b, s);
input [31:0] a, b; // operands
output reg [31:0] s; // sum - Could potentially use wire instead
integer i; // loop variable
reg [8:0] temp;
reg [47:0] intProd; // intermediate product
reg [23:0] tempA;
reg [23:0] tempB;
initial begin
//Initialization
for (i = 0; i < 48; i = i + 1) begin
intProd[i] = 0;
end
//Compute the sign for the result
if (a[31]^b[31] == 0) begin
s[31] = 0;
end
else begin
s[31] = 1;
end
//Compute the exponent for the result
#10 temp = a[30:23] + b[30:23] - 8'b11111111;
//Case for overflow
if(temp > 8'b11111110) begin
s[30:23] = 8'b11111111;
for (i = 0; i < 23; i = i + 1) begin
s[i] = 0;
end
$finish;
end
//Case for underflow
else if (temp < 8'b00000001) begin
for (i = 0; i < 31; i = i + 1) begin
s[i] = 0;
end
$finish;
end
else begin
s[30:23] = temp[7:0];
end
//Mutliply the signficands
//Make implicit one explicit
tempA[23] = 1;
tempB[23] = 1;
//Make operands 24 bits
for(i = 0; i < 23; i = i + 1) begin
tempA[i] = a[i];
tempB[i] = b[i];
end
//Compute product of signficands
intProd = tempA * tempB;
//Check and see if we need to normalize
if(intProd[47:46] >= 2'b10) begin
intProd = intProd >> 1;
temp = s[30:23] + 1'b1;
if(temp > 8'b11111110) begin
s[30:23] = 8'b11111111;
for (i = 0; i < 23; i = i + 1) begin
s[i] = 0;
end
$finish;
end
else
s[30:23] = temp[7:0];
end
s[22:0] = intProd[47:25];
end
endmodule
Here is my testbench:
module prob4;
reg [31:0] a, b;
wire [31:0] s;
// instantiate the floating point multiplier
prob3 f1(a, b, s);
initial begin
assign a = 32'h42055555;
assign b = 32'hBDCCCCCD;
#10 $monitor("s = %h", s);
assign a = 32'hBF555555;
assign b = 32'hCAB71B00;
#10 $monitor("s = %h", s);
a = 32'hFF500000;
b = 32'h7E700000;
#10 $display("s = %b", s);
a = 32'h01700000;
b = 32'h02F00000;
#10 $display("s = %b", s);
a = 32'hBE000000;
b = 32'h455F36DB;
#10 $display("s = %b", s);
a = 32'h3C800000;
b = 32'h3A800000;
#10 $display("s = %b", s);
a = 32'hC797E880;
b = 32'hB7FBA927;
#10 $display("s = %b", s);
end
endmodule
It displays the first value of s, but that is it. I'm honestly not too familiar with Verilog, so any clarification on why this might be happening would be truly appreciated.
The reason you are seeing only a single value for s is because all of your floating point logic (all the stuff in the prob3 module) is inside an initial block. Thus, you only run that code once; it starts at time 0, has a pause for 10 time units and finishes; never to run again. Here are a few tips for implementing the unit (assuming the module is suppose to be synthesizable and not just a functional verification model):
Place your combinational logic in an always #(*) block, not an initial block.
As toolic mentioned, only call $monitor once, and it will inform you whenever s or any other variables given as arguments change; thus you do not need the $display statements either unless you want to know the value of s at that point of execution (whether it changed or not and inline with the processes, so not necessarily the final value either). So typically your testbench main stimulus initial block would have $monitor() as the first line.
Don't call $finish inside your logic; ideally, you should set an error signal instead that the testbench might then choose to call $finish if it sees that error signal asserted.
Don't use assign inside procedural blocks (always, initial, etc), just say a = ... not assign a = ...

Systemverilog problem with always_comb construct

I have a problem with this SystemVerilog code. Here is the code:
module mult ( multiplicand, multiplier, Product, clk, clear, Startm, endm );
input [31:0] multiplicand;
input [31:0] multiplier ;
input clk;
input clear;
input Startm;
output logic [63:0] Product;
output logic endm;
enum logic [1:0] { inicio, multiplicar, nao_multiplicar, fim } estados;
logic [1:0] state;
logic [31:0] mplier;
logic [31:0] mplier_aux;
logic [31:0] mcand ;
logic [31:0] mcand_aux;
logic [63:0] Prod ;
logic [63:0] Prod_aux;
logic [5:0] cont;
logic [5:0] cont_aux;
initial begin
mplier = multiplier;
mplier_aux = multiplier;
mcand = multiplicand;
mcand_aux = multiplicand;
Prod = 0;
Prod_aux = 0;
state = inicio;
cont = 0;
cont_aux = 0;
end
always_ff #( posedge clk )
begin
if( clear )
begin
state <= inicio;
end
else if ( Startm )
begin
case( state )
inicio :
begin
if( mplier[0] == 0 )
begin
state <= nao_multiplicar;
end
else if( mplier[0] == 1 )
begin
state <= multiplicar;
end
end
multiplicar :
begin
if( cont == 32 )
state <= fim;
else if( mplier[0] == 0 )
begin
state <= nao_multiplicar;
end
else if( mplier[0] == 1 )
begin
state <= multiplicar;
end
end
nao_multiplicar:
begin
if( cont == 32 )
state <= fim;
else if( mplier[0] == 0 )
begin
state <= nao_multiplicar;
end
else if( mplier[0] == 1 )
begin
state <= multiplicar;
end
end
fim:
begin
state <= inicio;
end
endcase
end
end
always_comb
begin
case(state)
inicio:
begin
mplier = multiplier;
mcand = multiplicand;
Prod = 0;
cont_aux = cont + 1;
cont = cont_aux;
end
multiplicar:
begin
mcand_aux = mcand << 1;
mcand = mcand_aux ;
mplier_aux = mplier >> 1;
mplier = mplier_aux ;
Prod_aux = Prod + mcand;
Prod = Prod_aux;
cont_aux = cont + 1;
cont = cont_aux;
end
nao_multiplicar:
begin
cont_aux = cont + 1;
cont = cont_aux;
end
fim:
begin
Product = Prod;
endm = 1;
end
endcase
end
endmodule
I'm trying write a multiplicator with inputs of 32 bits and a product of 64 bits using
the Booth's algorithm. This error occur:
always_comb construct does not infer purely combinational logic
Why does this happens?
When describing combinational logic in always blocks, you have to make sure that all your variables are assigned to a value in all paths in your code. Otherwise a latch will be inferred. It's easy to miss something like this in traditional always blocks, so the always_comb block was introduced in SystemVerilog to explicitly check for this.
In your case, you've a few buses which are not assigned values in each branch of the case statement, for example mcand hasn't a value assigned to it in branches nao_multiplicar and fim.
There are 2 solutions. First is to, well, assign to all your variables in all your code branches.
Another solution is to write 'default' values for all of the variables in the always_comb before the case statement. In this way, each variable will always be assigned to a value each time the always_comb block triggers, and there'll be no warnings. YOur case statement then only needs to deal with the variables that need to change:
always_comb
begin
// Defaults (I think I got them all)
mplier = multiplier;
mcand = multiplicand;
Prod_aux = 0;
Prod = 0;
cont_aux = 0;
cont = 0;
Product = 0;
endm = 0;
// Now override the defaults when appropriate
case(state)
inicio:
begin
mplier = multiplier;
mcand = multiplicand;
Prod = 0;
cont_aux = cont + 1;
cont = cont_aux;
end
multiplicar:
begin
mcand_aux = mcand << 1;
mcand = mcand_aux ;
mplier_aux = mplier >> 1;
mplier = mplier_aux ;
Prod_aux = Prod + mcand;
Prod = Prod_aux;
cont_aux = cont + 1;
cont = cont_aux;
end
nao_multiplicar:
begin
cont_aux = cont + 1;
cont = cont_aux;
end
fim:
begin
Product = Prod;
endm = 1;
end
endcase
end
All the compile errors are eliminated when I get rid of the initial block. I'm using simulators from Cadence and Synopsys.
Here is a quote from the IEEE Std, 1800-2009, section 9.2.2.4 "Sequential logic always_ff procedure":
The always_ff procedure imposes the
restriction that it contains one and
only one event control and no blocking
timing controls. Variables on the
left-hand side of assignments within
an always_ff procedure, including
variables from the contents of a
called function, shall not be written
to by any other process.
There is a similar quote for always_comb.
The documentation is readily available from the IEEE. Your simulator should also have documentation.
The error message you receive from your tool seems not to be very helpful in this case.
always_comb will infer combinational logic, however, in your always_comb block you are doing assignments like C code, e.g:
always_comb
begin
...
cont_aux = cont + 1;
cont = cont_aux;
...
end
Here you are asking to make a combinational logic with feedback.
If you want to store values in time, you have to put your assignments in an always_ff block, which will infer sequential logic.
always_ff #(posedge clk)
begin
...
cont <= cont + 1;
...
end
The LRM is the most useful documentation I use for system verilog
http://www.vhdl.org/sv/SystemVerilog_3.1a.pdf

Assign integer to reg in Verilog

I have problems with this Verilog code. Basically, it won't let me do the Y = 3'di statement. Basically, I want Y to equal i. I am pretty sure the problem is the i. So, is there a way to do this in Verilog? Also, W is an input with 8 bits (in other words, W[7:0]).
for (i = 7; i >= 0; i = i - 1)
begin
if(W[i]) Y=3'di;
end
Thanks.
You can select bits using brackets .
for (i = 7; i >= 0; i = i - 1)
begin
if(W[i]) Y = i[2:0];
end
But it isn't even necessary if i was declared to be an integer. It will take however many bits fit in Y automatically and you only wanted the LSBs.
You might wish to use a case statement here:
case (1'b1)
W[0]: Y=3'd0;
W[1]: Y=3'd1;
W[2]: Y=3'd2;
W[3]: Y=3'd3;
W[4]: Y=3'd4;
W[5]: Y=3'd5;
W[6]: Y=3'd6;
W[7]: Y=3'd7;
default: Y=3'd0; // to avoid inferring a latch when W==8'd0
endcase
This makes the priority more obvious to readers of your code.
I have found that its better to use state machines to do "for-loop" routine.
Something like this:
module yourthing(clk, W, i, Y)
input clk;
input [7:0] W;
output [2:0] Y;
reg [2:0] i;
always#(posedge clk) begin
if(reset) begin
i = 3'd7;
Y = 3'd0;
end
else begin
case(i)
3'd7 : begin
if(W[i]) Y = i;
i = 3'd6;
end
3'd6 : begin
if(W[i]) Y = i;
i = 3'd5;
end
3'd5 : begin
if(W[i]) Y = i;
i = 3'd4;
end
3'd4 : begin
if(W[i]) Y = i;
i = 3'd3;
end
3'd3 : begin
if(W[i]) Y = i;
i = 3'd2;
end
3'd2 : begin
if(W[i]) Y = i;
i = 3'd1;
end
3'd1 : begin
if(W[i]) Y = i;
i = 3'd0;
end
3'd0 : begin
if(W[i]) Y = i;
i = 3'd7;
end
endcase
end
endmodule
Hope this helps...

Resources