4
\$\begingroup\$

I am trying to find a way to conditionally assign values to a signal in verilog similar to the with/select in VHDL. So far I found two ways https://www.chipverify.com/verilog/verilog-4to1-mux.

This is the first one:

module mux_4to1_assign ( input [3:0] a,                 // 4-bit input called a
                         input [3:0] b,                 // 4-bit input called b
                         input [3:0] c,                 // 4-bit input called c
                         input [3:0] d,                 // 4-bit input called d
                         input [1:0] sel,               // input sel used to select between a,b,c,d
                         output [3:0] out);             // 4-bit output based on input sel

   // When sel[1] is 0, (sel[0]? b:a) is selected and when sel[1] is 1, (sel[0] ? d:c) is taken
   // When sel[0] is 0, a is sent to output, else b and when sel[0] is 0, c is sent to output, else d
   assign out = sel[1] ? (sel[0] ? d : c) : (sel[0] ? b : a);

endmodule

Second one:

module mux_4to1_case ( input [3:0] a,                 // 4-bit input called a
                       input [3:0] b,                 // 4-bit input called b
                       input [3:0] c,                 // 4-bit input called c
                       input [3:0] d,                 // 4-bit input called d
                       input [1:0] sel,               // input sel used to select between a,b,c,d
                       output reg [3:0] out);         // 4-bit output based on input sel
                  
   // This always block gets executed whenever a/b/c/d/sel changes value
   // When that happens, based on value in sel, output is assigned to either a/b/c/d
   always @ (a or b or c or d or sel) begin
      case (sel)
         2'b00 : out <= a;
         2'b01 : out <= b;
         2'b10 : out <= c;
         2'b11 : out <= d;
      endcase
   end
endmodule

Both examples were taken from the link I shared before, my QUESTION IS if there is something in Verilog, similar to VHDL using the with/select, that is easy to understand without using procedural blocks?.

The first verilog example does the job but it takes a bit to understand the logic. Please keep in mind I am not complaining about or criticizing any language, I just want to know how to improve code readability for this particular case.

\$\endgroup\$
2
  • \$\begingroup\$ What do you mean by "better way"? Better readability? Optimized for speed/power/area? \$\endgroup\$ – Mitu Raj Apr 9 at 17:27
  • 1
    \$\begingroup\$ @MituRaj, you got it, I meant better readability, I will try to edit my post. Thanks \$\endgroup\$ – JC_Onp Apr 12 at 13:44
1
\$\begingroup\$

If you really want something based on an assign statement, your version can be improved:

// yours is below
assign out = sel[1] ? (sel[0] ? d : c) : (sel[0] ? b : a);

// but you can decode two bits at a time:
assign out = (sel==2'b00) ? a :
             (sel==2'b01) ? b :
             (sel==2'b10) ? c :
             (sel==2'b11) ? d :
             2'bx;  // should never hit this case, but you need an else

It's much more readable your version. If you're not used to the ternary conditional operator, well you just have to get used to it. It's part of C and many C-like languages (including Perl) but it's very widely used in Verilog since it's a natural multiplex operator, and it can be used in the middle of complex expressions. Very helpful, and something I miss a lot now that I'm at a VHDL company.

\$\endgroup\$
4
\$\begingroup\$

You can simplify the procedural block by using an implicit sensitivity list, always @* in Verilog and preferably always_comb in SystemVerilog. And you should not be using non-blocking assignments in combinational logic.

always_comb case (sel)
  2'b00 : out = a;
  2'b01 : out = b;
  2'b10 : out = c;
  2'b11 : out = d;
endcase

Almost the same amount of typing as the VHDL with/select.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.