basic parameterized multiplex and demultiplex

Post Reply
core
Posts: 9
Joined: April 5th, 2013, 3:00 pm

basic parameterized multiplex and demultiplex

Post by core » May 4th, 2013, 5:59 pm

In my web searching I found it painful to find a basic parameterized mux and demux module. The web is like the wild west full of partial examples. Here is what I finally came up with merging multiple suggestions and I think using names that make it more self documenting. I did not figure out the main code myself. I basically wanted to apply the software engineering Don't Repeat Yourself principle. Any time you repeat code or magic numbers where you should have defined a constant (e.g. a bit width or special value) it is more error prone. You may get bitten later when you fix a bug in one place but not others or your design changes slightly.
  • first you want to start a place for utility functions... even if it is only this one. "util.v"

    Code: Select all

    //////////////////////////////////////////////////////////////////////////////////
    // utility functions
    //////////////////////////////////////////////////////////////////////////////////
    
    // ceiling of log2.
    // (e.g. useful for calculating how many select lines are needed both internal to
    // a mux or demux and for any module interfacing to that mux)
    function integer clog2 (input integer n);
      integer j; 
      begin 
        n = n - 1;
        for (j = 0; n > 0; j = j + 1)        
          n = n >> 1;
        clog2 = j;
      end
    endfunction
    
  • next here are demux and mux whcih I have in "common.v"

    Code: Select all

    module demux (in, select, out);
      `include "util.v"
      parameter W_DATA = 1;
      parameter N_SELECT = 2;
      localparam W_SELECT = clog2(N_SELECT);
      input [W_DATA-1:0] in;
      input [W_SELECT-1:0] select;
      output [N_SELECT*W_DATA-1:0] out;
      
      genvar i;
      generate
        for (i = 0; i < N_SELECT; i = i + 1) begin : demux_out
    		assign out[(i*W_DATA)+:W_DATA] = (select == i) ? in : {W_DATA{1'b0}};
    	 end
      endgenerate
      
    endmodule
    
    module mux (in, select, out);
      `include "util.v"
      parameter W_DATA = 1;
      parameter N_SELECT = 2;
      localparam W_SELECT = clog2(N_SELECT);
      input [N_SELECT*W_DATA-1:0] in;
      input [W_SELECT-1:0] select;
      output [W_DATA-1:0] out;
      
      wire [W_DATA-1:0] channels[0:N_SELECT-1];
      
      assign out = channels[select];
      
      genvar i;
      generate
        for (i = 0; i < N_SELECT; i = i + 1) begin : mux_out
    		assign channels[i] = in[(i*W_DATA)+:W_DATA];
    	 end
      endgenerate
      
    endmodule
    
  • finally here is a top level test usage which just does demux and connects it back to a mux. It won't do anything on your Mojo, but you can play around with it in the simulator. "test_mux_demux.v"

    Code: Select all

    //////////////////////////////////////////////////////////////////////////////////
    // just a text for demux / mux
    //////////////////////////////////////////////////////////////////////////////////
    module test_mux(clk, rst, in, out);
      `include "util.v"
      parameter W_DATA = 2;
      localparam N_SELECT = 6;
      localparam W_SELECT = clog2(N_SELECT);
      input clk, rst;
      input [W_DATA-1:0] in;
      output [W_DATA-1:0] out;
    
    wire [N_SELECT*W_DATA-1:0] bus1;
    wire [W_DATA-1:0] bus2;
    
    reg [W_DATA-1:0] in_h, out_h;
    reg [W_SELECT-1:0] select_d, select_q;
    
    assign out = out_h;
    
    demux #(.W_DATA(W_DATA), .N_SELECT(N_SELECT)) demux1 (.in(in_h), .select(select_q), .out(bus1));
    mux #(.W_DATA(W_DATA), .N_SELECT(N_SELECT)) mux1 (.in(bus1), .select(select_q), .out(bus2));
    
    always @(select_q) begin
      assign select_d = (select_q < N_SELECT -1) ? select_q + 1 : {W_SELECT{1'b0}};
    end
    
    always @(posedge clk) begin
      if (rst) begin
        select_q <= {W_SELECT{1'b0}};
      end else begin
        select_q <= select_d;
      end
      in_h <= in;
      out_h <= bus2;
    end
      
    endmodule
    
DISCLAIMER: I've tested this in the simulator with my limited beginner skill, not with a good representative test set. Understanding how to use the simulator better is on my to do list. PLEASE test it yourself also.

Post Reply