Results 1 to 8 of 8

Thread: verilog- parameterized mux

  1. #1
    Join Date
    Jan 2008
    Posts
    27
    Rep Power
    1

    Default verilog- parameterized mux

    For the life of me I cannot figure out how to generate a parameterized mux in verilog...

    I understand how to generate, say, a 4:1 MUX of "N" bits WIDE... But I am trying to generate an N:1 mux, of only 1 bit wide.

    I've been scouring the googleweb for weeks with no such luck (aside from hit after hit for a variable-width mux)...

    Have I stumbled upon something impossible?

    thanks,
    ..dane

  2. #2
    Join Date
    Aug 2007
    Location
    Salt Lake City, Utah
    Posts
    1,692
    Rep Power
    1

    Default Re: verilog- parameterized mux

    I hope I'm not doing your homework for you. One of the shortcomings of Verilog is the inability to generate ports. So you have to bring the input in as a bus.

    I haven't compiled this so there may be errors:

    Code:
    module mux (#parameter  WIDTH           = 8,
                #parameter  CHANNELS        = 4) (
    
        input   [(CHANNELS*WIDTH)-1:0]      in_bus,
        input   [clogb2(CHANNELS-1)-1:0]    sel,   
    
        output  [WIDTH-1:0]                 out
        );
    
    genvar ig;
        
    wire    [WIDTH-1:0] input_array [0+:CHANNELS-1];
    
    assign  out = input_array[sel];
    
    generate
        for(ig=0; ig<CHANNELS; ig=ig+1) begin: array_assignments
            assign  input_array[ig] = in_bus[(ig*WIDTH)+:WIDTH];
        end
    endgenerate
    
    
    //define the clogb2 function
    function integer clogb2;
      input depth;
      integer i,result;
      begin
        for (i = 0; 2 ** i < depth; i = i + 1)
          result = i + 1;
        clogb2 = result;
      end
    endfunction
    
    endmodule

  3. #3
    Join Date
    Jan 2008
    Posts
    27
    Rep Power
    1

    Default Re: verilog- parameterized mux

    Quote Originally Posted by jakobjones View Post
    I hope I'm not doing your homework for you. One of the shortcomings of Verilog is the inability to generate ports. So you have to bring the input in as a bus.
    Hahaha.. no, you're not doing your homework for me. Truth be told it's a project I've been working on for a customer for about three months, and this is the last piece to the puzzle (the rest of the project is all done and working just fine) that I just can't seem to crack.

    I will admit to only a few years of experience with verilog, so your code snippet has a few curiosities in it that I'll ask below.

    Code:
    genvar ig;
        
    wire    [WIDTH-1:0] input_array [0+:CHANNELS-1];
    
    assign  out = input_array[sel];
    
    generate
        for(ig=0; ig<CHANNELS; ig=ig+1) begin: array_assignments
            assign  input_array[ig] = in_bus[(ig*WIDTH)+:WIDTH];
        end
    endgenerate
    I am not familiar with a "+" in the port width. A very quick google indicates maybe it's a polarity indicator, but that doesn't help me much -- can you explain what you're accomplishing by including it and how it would behave if it were excluded?

    I see what you're doing with your generate statement now, and feel a bit silly for not thinking of that myself. I was trying to go about it a much different (and obviously more difficult) way...

    I will mess around with your code snip and report back how it goes..

    thanks again,
    ..dane

  4. #4
    Join Date
    Aug 2007
    Location
    Salt Lake City, Utah
    Posts
    1,692
    Rep Power
    1

    Default Re: verilog- parameterized mux

    1 - That first "+" sign in the array declaration is a typo. See I told you there might be errors.
    .
    2 - The second "+:" sign in the "assign" statement is legitimate and is called a "Variable Vector Part Select" operator.
    For example, a statement like:
    assign data1 = data[8+:8]
    is equivalent to:
    assign data1 = data[15:8];

    Generically:
    assign data1 = data[x+:y]
    So the "+:" operator uses "x" as the starting index of the vector and uses "y" to determine how many bits of the vector to index. The "+:" operator adds "y" bits to "x" while the "-:" operand subtracts "y" bits from "x".

    Jake

    I will post some equivalent examples shortly.

  5. #5
    Join Date
    Aug 2007
    Location
    Salt Lake City, Utah
    Posts
    1,692
    Rep Power
    1

    Default Re: verilog- parameterized mux

    Equivalent / alternative examples
    1 - The one I already posted with a correction:
    Code:
    module mux (#parameter  WIDTH           = 8,
                #parameter  CHANNELS        = 4) (
    
        input   [(CHANNELS*WIDTH)-1:0]      in_bus,
        input   [clogb2(CHANNELS-1)-1:0]    sel,   
    
        output  [WIDTH-1:0]                 out
        );
    
    genvar ig;
        
    wire    [WIDTH-1:0] input_array [0:CHANNELS-1];
    
    assign  out = input_array[sel];
    
    generate
        for(ig=0; ig<CHANNELS; ig=ig+1) begin: array_assignments
            assign  input_array[ig] = in_bus[(ig*WIDTH)+:WIDTH];
        end
    endgenerate
    
    
    //define the clogb2 function
    function integer clogb2;
      input depth;
      integer i,result;
      begin
        for (i = 0; 2 ** i < depth; i = i + 1)
          result = i + 1;
        clogb2 = result;
      end
    endfunction
    
    endmodule
    2 - Similar to #1 but without using the "Variable Vector Part Select" operator:
    Code:
    module mux (#parameter  WIDTH           = 8,
                #parameter  CHANNELS        = 4) (
    
        input   [(CHANNELS*WIDTH)-1:0]      in_bus,
        input   [clogb2(CHANNELS-1)-1:0]    sel,   
    
        output  [WIDTH-1:0]                 out
        );
    
    genvar ig;
        
    wire    [WIDTH-1:0] input_array [0:CHANNELS-1];
    
    assign  out = input_array[sel];
    
    generate
        for(ig=0; ig<CHANNELS; ig=ig+1) begin: array_assignments
            assign  input_array[ig] = in_bus[((ig+1)*WIDTH)-1:(ig*WIDTH)];
        end
    endgenerate
    
    
    //define the clogb2 function
    function integer clogb2;
      input depth;
      integer i,result;
      begin
        for (i = 0; 2 ** i < depth; i = i + 1)
          result = i + 1;
        clogb2 = result;
      end
    endfunction
    
    endmodule
    3 - Equivalent logic without using a generate statement. I don't recommend this because some simulators don't work well with the "reg" type declaration for the array. Again, you could rewrite this to not use the "+:" operator if you wish.
    Code:
    module module mux (#parameter  WIDTH           = 8,
                #parameter  CHANNELS        = 4) (
    
        input   [(CHANNELS*WIDTH)-1:0]      in_bus,
        input   [clogb2(CHANNELS-1)-1:0]    sel,   
    
        output  [WIDTH-1:0]                 out
        );
    
    integer i;
        
    reg     [WIDTH-1:0] input_array [0:CHANNELS-1];
    
    assign  out = input_array[sel];
    
    always @*
        for(i=0; i<CHANNELS; i=i+1)
            input_array[i] = in_bus[(i*WIDTH)+:WIDTH];
    
    
    //define the clogb2 function
    function integer clogb2;
      input depth;
      integer i,result;
      begin
        for (i = 0; 2 ** i < depth; i = i + 1)
          result = i + 1;
        clogb2 = result;
      end
    endfunction
    
    endmodule
    Jake

  6. #6
    Join Date
    Jan 2008
    Posts
    27
    Rep Power
    1

    Default Re: verilog- parameterized mux

    Thanks again Jake for your help.. While cleaning up some of the project I found an optimization opportunity that greatly simplified the problem and made the mux much simpler. I really do appreciate your help though, I've learned a great deal from this thread!

    thank you!
    ..dane

  7. #7
    Join Date
    Mar 2007
    Posts
    1,853
    Rep Power
    1

    Default Re: verilog- parameterized mux

    Old post, but wondering if this ever synthesized? For me, Quartus synthesis errors out on the line:
    input [clogb2(CHANNELS-1)-1:0] sel,
    Stating:
    Error (10140): Verilog HDL error at param_mux.sv(6): range index is not constant
    (I just added another parameter for SEL_WIDTH, and used that, forcing the user to manually enter this value. It's easy enough to do, but not ideal...)

  8. #8
    Join Date
    Jan 2008
    Posts
    27
    Rep Power
    1

    Default Re: verilog- parameterized mux

    Hi Rysc,

    jakobjones suggested:

    Code:
    module mux (#parameter  WIDTH           = 8,
                #parameter  CHANNELS        = 4) (
    
        input   [(CHANNELS*WIDTH)-1:0]      in_bus,
        input   [clogb2(CHANNELS-1)-1:0]    sel,   
    
        output  [WIDTH-1:0]                 out
        );
    but I am implementing slightly differently. To continue jakobjones' example it would be:

    Code:
    module mux 
    (
    in_bus,
    sel,
    out
    );
    
    parameter WIDTH = 8;
    parameter CHANNELS = 4;
    
    input [(CHANNELS*WIDTH)-1:0] in_bus;
    input [clogb2(CHANNELS)-1:0] sel;
    output [WIDTH-1:0] out;
    
    //define the clogb2 function
    function integer clogb2;
      input depth;
      integer i,result;
      begin
        for (i = 0; 2 ** i < depth; i = i + 1)
          result = i + 1;
        clogb2 = result;
      end
    endfunction
    I haven't actually tried to synthesize jakobjones' example, so I cannot comment on its ability to be synthesized. However, my structure above which separates the port list declaration and their width definitions does synthesize. I will report however that I've been in the Xilinx world lately so I cannot comment on how the Quartus tools respond to the above example.

    good luck, and let us know how it goes.
    ..dane

Similar Threads

  1. Creating a 3:1 Clock Mux
    By drtomaslight in forum General Altera Discussion
    Replies: 7
    Last Post: December 17th, 2009, 07:17 AM
  2. Bus mux issues
    By andrewt12 in forum FPGA, Hardcopy, and CPLD Discussion
    Replies: 4
    Last Post: April 13th, 2009, 07:36 PM
  3. clkctrl input mux
    By vitzliputzli in forum FPGA, Hardcopy, and CPLD Discussion
    Replies: 6
    Last Post: October 13th, 2008, 10:58 PM
  4. Where can I find clock mux?
    By hapyang in forum General Altera Discussion
    Replies: 8
    Last Post: April 1st, 2008, 01:26 AM
  5. Mux - Verilog code question
    By dballesteros in forum Quartus II and EDA Tools Discussion
    Replies: 2
    Last Post: March 18th, 2008, 07:16 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •