多路复用器是一种组合电路,它从许多输入信号中选择一个作为输出,本文先介绍两个MUX的简单应用,主要关于如何将verilog与物理实现对应;第二当MUX作为时钟切换电路时如何避免毛刺(glitch)。
module xor_rill(
input a,
input b,
output z
);
assign z = a?(~b):b;
endmodule
问题:Create a 1-bit wide, 256-to-1 multiplexer. The 256 inputs are all packed into a single 256-bit input vector. sel=0 should select in[0], sel=1 selects bits in[1], sel=2 selects bits in[2], etc.
提示:不能用case结构
module top_module (
input [255:0] in,
input [7:0] sel,
output out
);
assign out = in[sel];
endmodule
多比特向量索引:
assign out = in[sel*4 +: 4];
assign out = in[sel*4+3 -: 4];
在SOC的设计中,经常需要用到大量的时钟源的选择与切换,以及时钟的分频,其中对于时钟的切换就显得尤为重要,并且如何在切换时钟源的过程中消除毛刺(glitch)。
对于一个时钟切换电路,输入两个异步时钟clk0、clk1,以及一个选择信号sel。我们直接使用2MUX就可以实现两个时钟源的切换,RTL代码也很简单:
assign clk_out = sel? clk1 :clk0;
clk0,clk1是异步的关系,所以就存在时钟切换会发生在任意时刻,也就会存在glitch的产生。当寄存器捕获到时钟沿其他没捕获到,极有可能造成系统的不稳定。
对于需要无缝切换时钟源,我们需要解决的问题有:
1.异步切换信号的跨时钟域同步问题,即可以用到异步复位,同步释放电路。
2.同步后的切换信号与时钟信号的逻辑设计。
`timescale 1ns/100ps
module clk_switch (
out_clk, // Outputs
clk_a, clk_b, select // Inputs
);
input clk_a;
input clk_b;
input select;
output out_clk;
wire out_clk;
reg q1,q2,q3,q4;
wire or_one, or_two,or_three,or_four;
always @ (posedge clk_a)
begin
if (clk_a == 1'b1)
begin
q1 <= q4;
q3 <= or_one;
end
end
always @ (posedge clk_b)
begin
if (clk_b == 1'b1)
begin
q2 <= q3;
q4 <= or_two;
end
end
assign or_one = (!q1) | (!select);
assign or_two = (!q2) | (select);
assign or_three = (q3) | (clk_a);
assign or_four = (q4) | (clk_b);
assign out_clk = or_three & or_four;
endmodule
`timescale 1ns/10ps
module clock_mux (
// OUTPUTs
//=========
output clk_out, // Clock output
// INPUTs
//=========
input clk_in0, // Clock input 0
input clk_in1, // Clock input 1
input reset, // Reset
input select_in // Clock selection
);
//----------------------------------------
// Regs declare
//----------------------------------------
reg dff0a,dff0b;
reg dff1a,dff1b;
wire clk_in0_inv = ~clk_in0;
wire clk_in1_inv = ~clk_in1;
//----------------------------------------
// clk_in0 path
//----------------------------------------
// negedge of clk_in0
always @(posedge clk_in0_inv or posedge reset)
if(reset)
dff0a <= 1'b1;
else
dff0a <= !select_in & !dff1b;
always @(posedge clk_in0 or posedge reset)
if(reset)
dff0b <= 1'b1;
else
dff0b <= dff0a;
wire clk_in0_gate = ~(~clk_in0 & dff0b);
//----------------------------------------
// clk_in1 path
//----------------------------------------
// negedge of clk_in1
always @(posedge clk_in1_inv or posedge reset)
if(reset)
dff1a <= 1'b0;
else
dff1a <= select_in & !dff0b;
always @(posedge clk_in1 or posedge reset)
if(reset)
dff1b <= 1'b0;
else
dff1b <= dff1a;
wire clk_in1_gate = ~(~clk_in1 & dff1b);
//-----------------------
// clock mux out
//-----------------------
assign clk_out = clk_in0_gate & clk_in1_gate;
endmodule
【1】数字集成电路设计-1-用一个mux和一个inv实现异或
【2】数字IC设计笔试问题系列–1(50题)
【3】HDLBits 系列(10)(Mux256to1)多路选择器的固定思维,你别想太多!
【4】SOC设计——时钟切换的MUX设计 glitch free技术(一种防止毛刺产生的多路选择器设计)