Reputation: 319
I am wondering if this syntax is allowed
always_comb begin
case (aaa)
3'b000: always #(CLKREF_HALF_PERIOD + 5000ps) xclk=~xclk ;//000 at 80MHZ :
3'b001: always #(3750ps + CLKREF_HALF_PERIOD) xclk=~xclk;//001 at 100MHZ
3'b010: always #(1250ps + CLKREF_HALF_PERIOD) xclk=~xclk;//010 at 200MHZ
3'b011: always #(0.252ns + CLKREF_HALF_PERIOD) xclk=~xclk;//011 at 333MHZ
3'b100: always #(0.112ns + CLKREF_HALF_PERIOD) xclk=~xclk;//100 at 367MHZ
default always #(CLKREF_HALF_PERIOD/1) xclk=~xclk;//default at 400MHZ
endcase
I am getting compilation errors regarding the nested always within the cases. i am trying to get the clock freq to change depending on the input of aaa. however the question is more of a question on "if an always within an always block is legal or not"
Upvotes: 0
Views: 6369
Reputation: 4381
Nested procedural blocks are not allowed. I believe that aaaaaa
is a parameter over here. If so, you can use generate
block. to use different clock frequencies. This will make a single combinational block active at a time. A sample code can be as follows:
generate
case (aaaaaa)
3'b000: always #(CLKREF_HALF_PERIOD + 5000ps) xclk=~xclk ;//000 at 80MHZ :
3'b001: always #(3750ps + CLKREF_HALF_PERIOD) xclk=~xclk;//001 at 100MHZ
3'b010: always #(1250ps + CLKREF_HALF_PERIOD) xclk=~xclk;//010 at 200MHZ
3'b011: always #(0.252ns + CLKREF_HALF_PERIOD) xclk=~xclk;//011 at 333MHZ
3'b100: always #(0.112ns + CLKREF_HALF_PERIOD) xclk=~xclk;//100 at 367MHZ
default always #(CLKREF_HALF_PERIOD/1) xclk=~xclk;//default at 400MHZ
endgenerate
If aaa
is a variable/register/wire then you can use forever
looping construct instead of inner always
block. Sample usage is shown more clearly in Dave_59's answer.
Refer IEEE 1800-2012 Section 27.5 for more information on generate
blocks.
Upvotes: 1
Reputation: 42738
The forever loop solution does not work because there is no way for the top level always
block to exit for the forever
loop and get to another branch of the case statement. A simpler solution is to use an always block to compute the clock delay, and another always block to create the clock.
int clk_delay;
always_comb
case (aaa)
3'b000: clk_delay = CLKREF_HALF_PERIOD + 5000ps; //000 at 80MHZ
3'b001: clk_delay = 3750ps + CLKREF_HALF_PERIOD; //001 at 100MHZ
...
always #clk_delay xclk = ! xclk;
Upvotes: 2