我正在研究具有以下要求的verilog代码: 它是完全同步的。 在11条总线之间实现多路复用,每条总线的宽度为8位。 它有2个周期的延迟。 它针对最大时钟频率进行了优化。
我到目前为止编写了这段代码:
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
现在我不确定如何合并最大clk频率部分以及2个时钟周期的计数器是否具有正确的逻辑。任何有关这方面的帮助将不胜感激。
试验台:
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
答案 0 :(得分:1)
要优化最大时钟频率,您需要最小化两个FF(流水线)之间的门逻辑。也就是说,不是在单个时钟周期内进行非常长的计算,而是需要时钟周期非常长(低频率),我们将计算分解为许多小的,并且由此做更多的时钟周期,但时钟周期较短(高频)。 很明显,这是延迟和吞吐量之间的权衡。
为了管理多路复用器,我建议使用分层多路复用树。 让我们说简单,你有4个输入。我们可以使用两个小型多路复用器将输入1和2并行输入到输入3和4。 我们可以对这两个多路复用器的输出进行采样,然后在mux 1和mux 2的输出之间的下一个多路复用器上进行采样,这是我们在前一个时钟周期计算的。
下面您可以看到一个4对1流水线多路复用器的示例,延迟为2。 您可以轻松地将其扩展为更多输入。 请注意:
就个人而言,我会把它写成完全不同的编码风格,但我尽量让它尽可能接近你的,让它对你来说更容易理解。此外,我没有检查它编译或行为符合预期
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