0

I am working on a verilog code with following requirements: It is Fully synchronous. Implement Muxes between 11 buses where each bus is 8-bits wide. It has 2 cycles of latency. It has Optimized for maximum clock frequency.

I have written this code so far:

    module muxcase (a,b,c,d,e,f,g,h,i,j,k, select, op, clk, reset);
input [7:0] a,b,c,d,e,f,g,h,i,j,k;
input [3:0] select;
output [7:0] op;
reg op;
input reset, clk;
integer count= 2’b00;
integer temp= 2’b00;
always @ (posedge clk)
begin 

if (reset==1’b1)
begin
count=2’b00;
op=8’b00000000;
select=4’b0000;
end
if (reset==1’b0)
begin 
if (count <3)
begin
count=count+1;
temp=count;
end
end

case (select)
4’b0000: op=a;
4’b0001: op=b;
4’b0010: op=c;
4’b0011: op=d;
4’b0100: op=e;
4’b0101: op=f;
4’b0110: op=g;
4’b0111: op=h;
4’b1000: op=i;
4’b1001: op=j;
4’b1010: op=k;
endcase

end
endmodule

Now i am not sure how to incorporate the maximum clk frequency part and whether my counter for 2 clock cycles has correct logic. Any help regarding that would be appreciated.

Test Bench:

    module mux_tb;
    reg [7:0] a,b,c,d,e,f,g,h,i,j,k;
    reg [3:0] select;

    wire [7:0] op;

    initial
    begin
    a =1,b =1,c = 0,d=0,e=0,f=1,g=1,h=0,i=1,j=0,k=1;
    s=4’b0000;
    #5 s=4’b0011;
    #5 s=4’b0111;
    #5 s=4’b1010;
    end
    muxcase f1 (a,b,c,d,e,f,g,h,I,j,k, select, op, clk, reset);

    endmodule
blackgreen
  • 34,072
  • 23
  • 111
  • 129
sar
  • 65
  • 1
  • 12
  • I will try and look more into this now. One problem I can tell you that you will have is an `implied latch`. An `implied latch` happens when not all of your cases are covered. In this case, you have 4-bits to use for all of your cases but you only use 0-10. Use a `default` case as so : `default: op=a` for example. – demogorgon Jul 16 '17 at 16:34
  • Ok thank you. I will add the default case. – sar Jul 16 '17 at 16:41
  • No prob, is `op` your output then? – demogorgon Jul 16 '17 at 16:44
  • Yes op is the output of mux – sar Jul 16 '17 at 16:46
  • Do you have a testbench written for this you could include as well? – demogorgon Jul 16 '17 at 17:00
  • I have added test bench in the post – sar Jul 16 '17 at 17:04
  • 1
    please indent the code in your example to make it readable. – Serge Jul 16 '17 at 23:13
  • Your single quotes must be `'`, not `’` (curved tail). This happens when you write your code with a word editor (like MS Word, wordpad, etc.) instead of a text editor (emacs, vim, notepad, etc.) or IDE. Also, a module cannot assign any of its input ports. You should use non-blocking assignments (`<=`) inside a synchronous blocks (`@(posedge clk)`). And `count` and `temp` don't do anything meaningful; they will be removed in synthesis. – Greg Jul 17 '17 at 17:42

1 Answers1

1

To optimize for maximum clock frequency you need to minimize the gate logic between two FFs (pipeline). That is, instead of doing very long calculation in a single clock cycle, and by that requiring the clock cycle being very long (low frequency), we break the calculation to many small ones, and by that doing more clock cycles, but the clock cycle is shorter (high frequency). So obviously, it's a tradeoff between latency and throughput.

To pipeline a mux, I would suggest using hierarchical mux tree. Let's say for simplicity that you have 4 inputs. We can mux inputs 1 and 2 in parallel to inputs 3 and 4, using two small muxes. We can sample the output of those two muxes, and then on the next cycle mux between the outputs of mux 1 and mux 2, which we calculated at the previous clock cycle.

Below you can see an example of a 4-to-1 pipelined mux with latency of 2. You can easily expand it to more inputs. Notice that:

  • you have 11 inputs to mux, so your mux tree will not be balanced.
  • You should use different bits of the select for each stage
  • You should sample the select along with data

Personally, I would have written it totally different coding style, but I tried to keep it as close as possible to yours, to make it more understandable for you. Also, I didn't check it compiles or behaves as expected

module pipelined_mux_4to1 (
    input clk, 
    input [1:0] select,
    input [7:0] a,
    input [7:0] b,
    input [7:0] c,
    input [7:0] d,
    output reg [7:0] out
);

//first cycle muxes
reg [7:0] mux_a_b;

always @*
     case (select[0])
         1'b0 : mux_a_b = a;
         1'b1 : mux_a_b = b;
         default: mux_a_b = {7{1'bx}};
     endcase

reg [7:0] mux_c_d;

always @*
     case (select[0])
         1'b0 : mux_c_d = c;
         1'b1 : mux_c_d = d;
         default: mux_c_d = {7{1'bx}};
     endcase

//sample first muxes stage and the select
reg [7:0] mux_a_b_ff;
reg [7:0] mux_c_d_ff;
reg select_msb_ff;

always @(posedge clk) begin
      mux_a_b_ff <= mux_a_b;
      mux_c_d_ff <= mux_c_d;          
      select_msb_ff <= select[1];
end

//second cycle mux    
reg [7:0] mux_final;

always @*
     case (select_msb_ff)
         1'b0 : mux_final = mux_a_b_ff;
         1'b1 : mux_final = mux_c_d_ff;
         default: mux_final = {7{1'bx}};
     endcase

//sample second mux stage
always @(posedge clk)
     out <= mux_final;

endmodule
EEliaz
  • 155
  • 8