FPGA 译码器+解码器 (含代码)

译码器

首先从大家最熟悉的38译码器开始讲解,38译码器是指将3位2进制数(ABC)通过电路转换成八路不同状态的输出(Y0-Y7),真值表入下图:

框图如下: 

在clk到来时,译码器每输入一个3位2进制的变量a,译码器encode会输出一个8位2进制的b,a和b对应38译码器真值表

译码器输入输出说明:

名称

方向

位宽

类型

说明

扫描二维码关注公众号,回复: 14417418 查看本文章

clk

I

1

wire

时钟信号,高电平有效

reset

I

1

wire

复位信号,高电平复位

a

I

3

wire

输入信号

b

O

8

reg

输出信号

代码如下:

module encode(
input clk ,
input reset,
input [2:0] a,
output reg [7:0] b
    );
    
    always@(posedge clk)begin
    	
    	if(reset)begin
    		b<=8'd0;
    	end
    	else begin
    		case(a)
    			3'd0:begin
    				b<=8'b0000_0001;//注意真值表为非
    			end
    			3'd1:begin
    				b<=8'b0000_0010;
    			end
    			3'd2:begin
    				b<=8'b0000_0100;
    			end
    			3'd3:begin
    				b<=8'b0000_1000;
    			end
    			3'd4:begin
    				b<=8'b0001_0000;
    			end
    			3'd5:begin
    				b<=8'b0010_0000;
    			end
    			3'd6:begin
    				b<=8'b0100_0000;
    			end
    			3'd7:begin
    				b<=8'b1000_0000;
    			end	
    		
    		endcase
    	end
    end
    
endmodule

下面进行仿真:

module TB_encode(

    );
reg clk  ;
reg reset;
reg [2:0]a =0   ;
wire [7:0]b  ;  
    
    encode inst_encode(
       .clk     (clk)  ,
       .reset   (reset)  ,
       .a       (a)  ,
       .b       (b)
    );
    
    initial begin
    	clk=0;
    	reset=1;
    	#20;
    	reset=0;
    
    	
    end
    
    always #20 clk=~clk;
    
    always@(posedge clk)begin
    	if(reset)begin
    		a<=3'd0;
    	end
    	else begin
    		if(a==3'd7)begin
    			a<=3'd0;
    		end
    		else begin
    			a<=a+1;
    		end
    	end
    end
endmodule

 仿真结果正确:

  

解码器

依然先举例最熟悉的83解码器,83解码器是将8输入的二进制变量,得到3输出变量,与38编码器正好相反,框图如下:

在clk到来时,译码器每输入一个8位2进制的b,译码器encode会输出一个3位2进制的c,c和b对应83解码器真值表

输入输出说明:

名称

方向

位宽

类型

说明

clk

I

1

wire

时钟信号,高电平有效

reset

I

1

wire

复位信号,高电平复位

a

I

8

wire

输入信号

c

O

3

reg

输出信号

module decode(
input clk,
input reset,
input [7:0] b,
output [3:0] c
    );
    
    always@(posedge clk)begin
    	if(reset)begin
    		c<=3'd0;
    	end
    	else begin
    		case(b)
    			8'b1111_1110:begin
    				c<=3'd0;
    			end
    			8'b1111_1101:begin
    				c<=3'd1;
    			end
    			8'b1111_1011:begin
    				c<=3'd2;
    			end
    			8'b1111_0111:begin
    				c<=3'd3;
    			end
    			8'b1110_1111:begin
    				c<=3'd4;
    			end
    			8'b1101_1111:begin
    				c<=3'd5;
    			end
    			8'b1011_1111:begin
    				c<=3'd6;
    			end
    			8'b0111_1111:begin
    				c<=3'd7;
    			end
    			
    		endcase
    	end
    end
endmodule

显而易见,就是38译码器的反过程,写一个仿真文件进行仿真,代码如下:

module TB_decode(

    );

reg  clk    ;
reg  reset  ;
reg  [7:0]b=8'b0000_0001 ;   
wire  [3:0]c;    

    
    decode inst_decode(
      .clk   (clk),
      .reset (reset),
      .b     (b),
      .c     (c)
    );
    
    initial begin
    	clk=0;
    	reset=1;
    	#20
    	reset=0;
    	b<=8'b0000_0001;
    end
    
    always #20 clk=~clk;
    
    always@(posedge clk)begin
    	if(reset)begin
    		b<=8'b0000_0001;
    	end
    	else begin
    		if(b==8'b1000_0000)begin
    			b<=8'b0000_0001;
    		end
    		else begin
    			b<=b<<1;//1左移
    		end
    	end
    end
endmodule

仿真结果正确:

译码器-解码器联合

把a输入编码器,将译码器输出的b,输入编码器b,最后输出c。系统框图如下:

​​​​​​​ 

将系统输入的50MHZ的clk输给PLL,输出25MHZ的clk

PLL的locked信号与encode和decode的reset相连接

输入[2:0]a给encode输出[7:0]的b,把输出[7:0]的b输入decode(用b_wire连接),输出[2:0]c

系统需将clk_25m输出,用于系统a的输入

关于PLL配置的大家可以看这篇 使用锁相环输出时钟信号_居安士的博客-CSDN博客_锁相环时钟

输入输出说明:

名称

方向

位宽

类型

Clk_50m

In

1

Wire

a

In

3

Wire

Clk_25m

Out

1

Wire

c

out

3

reg

 

最后结果如上图,a等于c,b是8位 

完整代码放这里:

https://download.csdn.net/download/weixin_46188211/85640406

猜你喜欢

转载自blog.csdn.net/weixin_46188211/article/details/125272087