Verilog: Can you put "assign" statements within always@ or begin/end statements?
Is this allowed?
input w;
input [8:0]y;
output reg [8:0]x;
always@(w)
begin
//x[0] or A is never on in any next state
assign x[0] = 0;
assign x[1]= (y[0]&~w) | (y[5]&~w) | (y[6]&~w) | (y[7]&~w) | (y[8]&~w); //B
assign x[2]= (y[1]&~w); //C
assign x[3]= (y[2]&~w); //D
assign x[4]= (y[3]&~w) | (y[4]&~w); //E
assign x[5]= (y[0]&w) | (y[1]&w) | (y[2]&w) | (y[3]&w) | (y[4]&w); //F
assign x[6]= (y[5]&w);
assign x[7]= (y[6开发者_开发知识库]&w);
assign x[8]= (y[7]&w) | (y[8]&w);
end
You can, it's called a "Procedural Continuous Assignment". It overrides ordinary procedural assignments, there doesn't seem to be a call for them in the code you've posted. I'm not sure if they're synthesisable, but I never have cause to use them anyway.
A note on your code - you're missing y
from your sensitivity list: eg always @( w or y )
or always @(*)
is safer.
Building upon Marty's answer, you should read section 9.3 of the IEEE Verilog Standard (1364-2005, for example), where it describes "Procedural Continuous Assignment". The spec allows for assign
statements within an always
block. However, from my experience, it is quite rare.
Another issue with your code is that it has compile errors with two different simulators that I tried. Both generate error messages that bit-selects or part-selects cannot be used on the left hand side of the assignment.
Another possible solution is to get rid of the always
block, and just use simple continuous assignments.
input w;
input [8:0] y;
output [8:0] x;
assign x[0] = 0;
assign x[1]= (y[0]&~w) | (y[5]&~w) | (y[6]&~w) | (y[7]&~w) | (y[8]&~w); //B
assign x[2]= (y[1]&~w); //C
assign x[3]= (y[2]&~w); //D
assign x[4]= (y[3]&~w) | (y[4]&~w); //E
assign x[5]= (y[0]&w) | (y[1]&w) | (y[2]&w) | (y[3]&w) | (y[4]&w); //F
assign x[6]= (y[5]&w);
assign x[7]= (y[6]&w);
assign x[8]= (y[7]&w) | (y[8]&w);
The procedural continuous assign
statement was intended to be an optimized way of writing a mux-like behavior. For example, if you have
always @(A or B or select)
if (select)
out = A;
else
out = B;
You could write this as
always @(select)
assign out = A;
else
assign out = B;
But people don't like having to deal with sensitivity lists, so @(*)
was added to Verilog, and SystemVerilog added always_comb
.
But the real killer for this construct is that many people would write code like
always @(*)
assign out = A;
Which simulates fine, but you now have a double penalty in performance because the assign
statement is already sensitive to changes in A, but so is the always
block. This repeatedly executes the procedural assign
statement replacing the same RHS.
Assign is a continuous assignment statement which is used with wires in Verilog. assign statements don't go inside procedural blocks such as always. Registers can be given values in an always block.
Assign statements can be viewed as:
always @(*)
statements for wires.
Yes, but you don't want to. Since x[] doesn't depend on x[] the order doesn't matter. Just use <= instead of assign =.
There is no need using assign inside a procedural block (In this case Always)
Assign is a continuous assignment, and it has to go outside a procedural block.
- Thinking from the circuit level: this always(w) begin ..... end , so every code inside it will be activated whenever w is changed ie it falls or raise .
- assign statement requires pin/port which it assign to some wire or reg output
- its a complete combinational circuit I am unable to see how the same will only activate at w, that is who/what circuit will make it to only change when w either rises or fall
- anyway you cant assign a reg output to some wire/reg output using assign statement because as I said it requires you to put pin/port to be assigned only
- anyway if you go for basic verilog and not so called "Procedural Continuous Assignment" i guess its weird to use the same .
精彩评论