四选一多路选择器、3-8译码器; 序列检测(连续和含无关项的)

243 阅读3分钟

四选一多路选择器

image.png

分析: 线网只能使用连续赋值语句进行赋值,因此不能使用always组合逻辑块。

通过sel[0]的数值判断,再判断sel[1]的数值,即可判断选择哪一个信号。

sel 00 -d3

01 - d2 10 - d1 11- d0 方法1: 三目运算符

module mux4_1(
input [1:0] d1,d2,d3,d0;
input [1:0] sel;
output  [1:0]mux_out
);
    
    assign mux_out = sel[0]?(sel[1]?d0:d2):(sel[1]?d1:d3);    

endmodule

方法2:case语句 利用always语句的组合逻辑,使用中间寄存器寄存数据。 assign赋值给mux_out

begin和end之间使用reg类型,阻塞或者非阻塞都可以。

module mux4_1(
input [1:0] d1,d2,d3,d0;
input [1:0] sel;
output  [1:0]mux_out
);
    reg [1:0] mux_out_reg;
    always@(*)
    begin
        case(sel)
            2'b00:mux_out_reg = d3;
            2'b01:mux_out_reg = d2;
            2'b10:mux_out_reg = d1;
            2'b11:mux_out_reg = d0;
        default:
            mux_out_reg = d0;
        endcase
     end
     
 assign mux_out = mux_out_reg;
      

endmodule

3-8译码器:

moudule 
(a,b,c,out);
input a,b,c;
ouput reg [7:0] out;

always@(a,b,c)
begin
    case({a,b,c})
        3'b000: out = 8'b0000_0001;
        3'b001: out = 8'b0000_0010;
        3'b010: out = 8'b0000_0100;
        3'b011: out = 8'b0000_1000;
        3'b100: out = 8'b0001_0000;
        3'b101: out = 8'b0010_0000;
        3'b110: out = 8'b0100_0000;
        3'b111: out = 8'b1000_0000;
        
    endcase
    
 end
 
endmodule

输入序列连续的序列检测:

检测输入信号满足01110001序列

使用序列缓存 对比法:

将8个时刻的数据缓存,作为一个数组,每个时刻的输入位于数组的末尾,数组其他元素左移,把最早输入的数据移出。然后将数组和目标序列对比,如果数组和目标序列相等,则说明出现目标序列。

//序列缓存,位拼接实现,序列左移。 低7位作为高7位

a_temp <= {a_temp[6:0],a};

序列缓存+序列判断 确定输出

module sequence_detect(
	input clk,
	input rst_n,
	input a,
	output reg match
	);

    reg [7:0]a_temp;
    //序列检测 输出
    always@(posedge clk or negedge rst_n)
        if(rst_n == 1'b0)
            match <= 1'b0;
        else if(a_temp == 8'b0111_0001)   
            match <= 1'b1;
        else
             match <= 1'b0;
    //序列缓存,位拼接实现,序列左移。 低7位作为高7位
    always@(posedge clk or negedge rst_n)
        if(rst_n == 1'b0)
            a_temp <= 8'b0;
        else 
            a_temp <= {a_temp[6:0],a};

  
endmodule

含有无关项的序列检测

检测序列 011xxx 100序列。

序列缓存法: 将九个时刻的数据缓存,作为数组,每个时刻的输入位于数据末尾,数组其他元素左移,把最早输入的数据移出,然后截取数组前三位和目标序列011对比,截取数组后三位与目标序列110对比。

移位可以通过位截取和位拼接操作实现,{a_temp[7:0],a}

module sequence_detect(
	input clk,
	input rst_n,
	input a,
	output reg match
	);

    reg [8:0]a_temp;
    
    always@(posedge clk or negedge rst_n)
        if(!rst_n)
            match <= 1'b0;
        else if(a_temp[8:6] == 3'b011 && a_temp[2:0] == 3'b110)
            match <= 1'b1;
        else
             match <= 1'b0;
   
    
    always@(posedge clk or negedge rst_n)
        if(!rst_n)
            a_temp <= 9'b0;
        else 
            a_temp <= {a_temp[7:0],a};
    

    
    
    
    
    
    
    
  
endmodule
```