UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Observer townsend
Observer
1,378 Views
Registered: ‎02-08-2019

combinational logic mux

Jump to solution

Hi, I'm new to all this and I don't see an appropriate board for my question. Since this is my first post here, I thought I'd do a quick post to the "welcome and join" board. Can someone tell me which board is most appropriate for beginner level questions? In particular, I am having trouble convincing verilog to do a combinational logic circuit on something I know can be done that way - it wants me to use a register, but I don't want clocked logic. I copied an example off the internet I found of something the author described as a combinational implementation of a multiplexer, but when I tried it verbatim, I still got the "procedural assignment to a non-register, etc." error. Before I start typing in specific verilog code to ask about, can you tell me which board should I post my querry to? Thanks!

-gt-

 

0 Kudos
1 Solution

Accepted Solutions
Historian
Historian
1,238 Views
Registered: ‎01-23-2009

Re: combinational logic mux

Jump to solution

You are probably suffering from the classic confusion between a "Verilog reg" and a "register (i.e. flip-flop)" - they are not the same thing.

A Verilog "reg" is a construct of the language - it is a "register" as in a register in any other programming language (after all Verilog is nothing more than a programming language). Like all other registers in programming languages, a register is "given a value" which it keeps until it is given a new one. It is nothing more than that. It is neither a flip-flop, a latch, nor a combinatorial element.

The Verilog language can be used to describe hardware. The (one and pretty much only) rule of a synthesis tool is to replace HDL code (Verilog/VHDL/SystemVerilog) with an interconnection of hardware cells so that the resulting network has exactly the same behavior as the HDL code.

If you have a reg in always block where the reg is given a new value whenever any of the inputs to that always block change (and for all combinations of the inputs to the block), then you get a combinatorial network - an interconnection of LUTs and other combinatorial cells.

If you have a reg in an always "@(posedge clk)" block - i.e. a reg that takes a new value on the rising edge of every clock, then you get a flip-flop.

If you have an always block where a reg is given a new value under some conditions, but not all conditions, then you get a latch - the HDL code describes a condition where "sometimes the reg gets a new value, and sometimes it doesn't which means that it keeps the old value". This is the description of a latch.

So, if you have a case statement where every branch of the case statement results in a reg getting a new value that can be derived purely from the inputs, then you have a combinatorial process. If you have even one case where the reg does not get a new value, it must keep the old one, which is a latch.

Avrum

Tags (1)
9 Replies
Scholar u4223374
Scholar
1,347 Views
Registered: ‎04-26-2015

Re: combinational logic mux

Jump to solution

This forum is fine for that sort of thing. Or you can use the General Technical Discussion one.

 

Just post your code here and we'll see what's wrong. I would guess that the problem is just a very common misconception: that "reg" actually creates a register. In fact, "reg" only creates a register if it's written from a clocked (ie sequential logic) block. If it's written from a combinational block which defines the output in every case (as a mux should) then you get a wire, and if it's from a combinational block which sometimes doesn't define the output then you get a latch (which is generally bad news).

 

Because of this, you can define the output from your combinational logic block as a "reg" without creating a register - which will probably stop the tools complaining.

0 Kudos
Observer townsend
Observer
1,337 Views
Registered: ‎02-08-2019

Re: combinational logic mux

Jump to solution

Ah great! Thanks so much for responding. Okay, then let's cut straight to the chase then.  I've taken your advice and set the outputs to "reg" and I'm in the process of wading through the schematic to see if it worked, however this is a little cog in a huge project and the schematic is just a big "blob" until you zoom WAY, WAY, in, so its really hard to find things and relate them to the original code. I MAY have to synthesize it separately to see how it "schematics" out.

In the meantime, I'll cut and past my actual code (not the example I was testing earlier) for your comments on whether it should wind up combinational despite the "reg" declaration. In doing so, I have another question related to this: I note that often Vivado is smart enough to make unexpected (correct) simplifications. If you look at the 24 constants that this solution needs to select in pairs, you'll note that many of the bits (and there are 64 of them in each!) are zeros. Is it likely that Vivado will realize that and NOT actually multiplex them, or do I need to "give it some help" by weeding out such bits and not including them in the multiplexer?

The device selects a pair of contstants from 24 constants and routes the selected pair of 64 bit "keys" to two 64-bit outputs. A four bit "sel" value from 0000 to 1011 determines which pair will be selected. So, just to be clear, the question is two-fold: i) will this be combinational? and ii) will the abundance of common zeros in the keys automatically NOT be included in the final circuit implementation? Here's my code:


module keypair(input wire [3:0] pair_sel,
output reg [63:0] key0,
output reg [63:0] key1);

localparam krndc0 = 64'h0000000000000001;
localparam krndc1 = 64'h0000000000008082;
localparam krndc2 = 64'h800000000000808a;
localparam krndc3 = 64'h8000000080008000;
localparam krndc4 = 64'h000000000000808b;
localparam krndc5 = 64'h0000000080000001;
localparam krndc6 = 64'h8000000080008081;
localparam krndc7 = 64'h8000000000008009;
localparam krndc8 = 64'h000000000000008a;
localparam krndc9 = 64'h0000000000000088;
localparam krndc10 = 64'h0000000080008009;
localparam krndc11 = 64'h000000008000000a;
localparam krndc12 = 64'h000000008000808b;
localparam krndc13 = 64'h800000000000008b;
localparam krndc14 = 64'h8000000000008089;
localparam krndc15 = 64'h8000000000008003;
localparam krndc16 = 64'h8000000000008002;
localparam krndc17 = 64'h8000000000000080;
localparam krndc18 = 64'h000000000000800a;
localparam krndc19 = 64'h800000008000000a;
localparam krndc20 = 64'h8000000080008081;
localparam krndc21 = 64'h8000000000008080;
localparam krndc22 = 64'h0000000080000001;
localparam krndc23 = 64'h8000000080008008;

always @(*)
   begin
      case(pair_sel)
         4'b0000: begin
            key0 = krndc0;
            key1 = krndc1;
         end
         4'b0001: begin
            key0 = krndc2;
            key1 = krndc3;
         end
         4'b0010: begin
            key0 = krndc4;
            key1 = krndc5;
         end
         4'b0011: begin
            key0 = krndc6;
            key1 = krndc7;
         end
         4'b0100: begin
            key0 = krndc8;
            key1 = krndc9;
         end
         4'b0101: begin
            key0 = krndc10;
            key1 = krndc11;
         end
         4'b0110: begin
            key0 = krndc12;
            key1 = krndc13;
         end
         4'b0111: begin
            key0 = krndc14;
            key1 = krndc15;
         end
         4'b1000: begin
            key0 = krndc16;
            key1 = krndc17;
         end
         4'b1001: begin
            key0 = krndc18;
            key1 = krndc19;
         end
         4'b1010: begin
            key0 = krndc20;
            key1 = krndc21;
         end
4'b1011: begin
            key0 = krndc22;
            key1 = krndc23;
         end
      endcase
end

 

0 Kudos
Highlighted
Teacher xilinxacct
Teacher
1,305 Views
Registered: ‎10-23-2018

Re: combinational logic mux

Jump to solution

@townsend

The sparseness of the case statement is fine... you will not pay for the empty spaces.

The declaration of 'reg' will indeed insert a LDCE between the input and output... so, combinational between the LDCE and the output, but not strictly between input and output.

They 'may' (and probably is) be someway to do that in verilog, but I don't use it enough to know. (e.g. if you can get way with 'integer' your verlog might be fine, but I don't think you can size your integer in verilog, so you may need 4 values.) However, VHDL will trivially generate pure combinational for this type of thing.

Hope that helps

If so, please mark as solution accepted. Kudos also welcomed. :-)

Observer townsend
Observer
1,283 Views
Registered: ‎02-08-2019

Re: combinational logic mux

Jump to solution

When you refer to "the sparseness of the case statment" if I understand correctly you are referring to the fact that there are 16 possible states but I've only defined twelve. However, that's not what I was asking about. If you look at the inputs, which consist of twelve pairs of constant 64 bit integers, you'll see that each of these numbers only has a few one bits, but most of the bits in these 24 numbers are all zeros. I was asking whether I should blindly route these roughly 1400 bits of zeros through the mux in hopes that vivado will realize that its a waste of circuitry, or should I just omit the associated bits of the 24 input values and two output values  from the circuit altogether and just set the corresponding outputs to ground. Is Vivado smart enough to do that? If so, I can keep my code more abstract. If not, I should only route the required bits through the mux.

About the other issue, if Vivado is happy if "integer" is specified, what is the reasoning behind the language squaking about a collection of general signals that haven't been labeld as an "integer" ... I mean after all, an integer can always be viewed as an associated collection of bits, so why should it matter that it is not labeld as an integer? (I'm not doubting your advice here, but I'm just questioning why, from a "programming language" perspective this would make any sense. OR, is it the case that even if I say "integer" it is still going to toss in a register into the mix?

Finally, did I understand you correctly in saying that its going to toss in a register REGARDLESS of what I try to do? If so, would that mean my only choice is to actually craft a full combinational circuit and hard code it with no abstraction structures (like a case statment) to get what I want?

I mean, I want this thing to spit out the result as soon as it can be generated based on the input values without having to artificially wait for the next clock cycle. Having to "force" vivado to do what I want by dropping to the low level of boolean equations seems to defeat the purpose of the language.

-gt-

0 Kudos
Historian
Historian
1,281 Views
Registered: ‎01-23-2009

Re: combinational logic mux

Jump to solution

The only issue with your code comes from the question "What do you want the output to be when the pair_sel is not one of the ones you described".

As coded, there is no assignment to the registers, so by the definition of how Verilog works, the answer is "don't change the values" - this means a latch.

If you want to avoid the latch, you need to define an output value for all 16 possible cases - this can be done with a default: case - either to set the values to some arbitrary value (like 0), or to simply replace your last real one - simply replace "4'b1011:" with "default:".

Avrum

Observer townsend
Observer
1,279 Views
Registered: ‎02-08-2019

Re: combinational logic mux

Jump to solution

Thanks for that clarification Avrum, that makes sense. Are you saying that if I include a default case then verilog WON'T toss in a register?

-gt-

 

0 Kudos
Historian
Historian
1,239 Views
Registered: ‎01-23-2009

Re: combinational logic mux

Jump to solution

You are probably suffering from the classic confusion between a "Verilog reg" and a "register (i.e. flip-flop)" - they are not the same thing.

A Verilog "reg" is a construct of the language - it is a "register" as in a register in any other programming language (after all Verilog is nothing more than a programming language). Like all other registers in programming languages, a register is "given a value" which it keeps until it is given a new one. It is nothing more than that. It is neither a flip-flop, a latch, nor a combinatorial element.

The Verilog language can be used to describe hardware. The (one and pretty much only) rule of a synthesis tool is to replace HDL code (Verilog/VHDL/SystemVerilog) with an interconnection of hardware cells so that the resulting network has exactly the same behavior as the HDL code.

If you have a reg in always block where the reg is given a new value whenever any of the inputs to that always block change (and for all combinations of the inputs to the block), then you get a combinatorial network - an interconnection of LUTs and other combinatorial cells.

If you have a reg in an always "@(posedge clk)" block - i.e. a reg that takes a new value on the rising edge of every clock, then you get a flip-flop.

If you have an always block where a reg is given a new value under some conditions, but not all conditions, then you get a latch - the HDL code describes a condition where "sometimes the reg gets a new value, and sometimes it doesn't which means that it keeps the old value". This is the description of a latch.

So, if you have a case statement where every branch of the case statement results in a reg getting a new value that can be derived purely from the inputs, then you have a combinatorial process. If you have even one case where the reg does not get a new value, it must keep the old one, which is a latch.

Avrum

Tags (1)
Observer townsend
Observer
1,185 Views
Registered: ‎02-08-2019

Re: combinational logic mux

Jump to solution

Yes, that was exactly my problem - thanks for "leading me to the light."

Now I just need someone to tell me if verilog is smart enought to ignore those 1400 common constant zeros in all my inputs and not actually provide circuitry to route them all through to the outputs.   :)

0 Kudos
Historian
Historian
1,164 Views
Registered: ‎01-23-2009

Re: combinational logic mux

Jump to solution

Now I just need someone to tell me if verilog is smart enought to ignore those 1400 common constant zeros in all my inputs and not actually provide circuitry to route them all through to the outputs.   :)

It will. Synthesis can do very aggressive Boolean optimization. Each of your 2x64 bit outputs represents an (at most) 16-1 MUX of constant bits. Synthesis will generate (the equivalent of) a Karnaugh map for each bit and produce the smallest Boolean circuit for each bit. In fact, since there is only one 4 bit independent variable in your system (the pair_sel) each of your 128 output bits will at most be a LUT4, with the output bits that correspond to the bit positions where all the constants are 0 being nothing at all (the output bit will just be logic0). So this entire case statement will result in something significantly less than 128 LUTs. In fact, since the LUT6 in all the modern technologies can do two independent functions of up to 5 inputs, each pair of output bits will take one LUT6; thus you will use significantly less than 64 LUT6s - this is tiny.

Avrum