#FPGA#Verilog实现简单组合逻辑电路

测试文件写法参考:使用VIVADO编写简单的Verilog程序和Testbench

加法器

半加器

  • 其真值表如下:
    在这里插入图片描述

  • 其电路图为
    在这里插入图片描述

  • 其表达式为
    在这里插入图片描述
    在这里插入图片描述

  • 实现代码

`timescale 1ns / 1ps

module half_adder(
    input a,b,
    output sum,cout
    );
    
	assign sum=a ^ b;
	assign cout=a & b;

endmodule

  • 测试文件
module tb_half_adder();
//一般将待测试模块的输入设置为reg,输出设置为wire即可
reg a,b;
reg clk;//clk是时钟
wire sum,cout;

initial 
	begin//#表示时延,开始的时候电流可能有点不稳定,后面a和b代表信号的初始化
		#1
		a = 0;
		b = 0;
		clk = 0;
	end
always #5 clk = ~clk;//这个#5也表示时延5个周期,并且always可以用于组合逻辑和时序逻辑,clk = ~clk必须有时延,否则会形成"死锁",代表时序逻辑,信号在这儿停留5个周期
always @(posedge clk)//这个表示触发条件是:边沿触发
	begin//这个表示产生随机数
		a = {$random} % 2;
		b = {$random} % 2;
	end
half_adder u1(a,b,sum,cout);//这个是调用原来的仿真文件,我们这个是顺序对应,所以不需要.a(a)这么写了
endmodule

  • vivado仿真出来的电路图
    在这里插入图片描述
  • modelsim仿真出来的测试波形
    在这里插入图片描述

全加器

  • 其真值表如下
    在这里插入图片描述

  • 其电路图如下
    在这里插入图片描述

  • 其表达式如下
    在这里插入图片描述
    在这里插入图片描述

  • 实现代码

`timescale 1ns / 1ps

module adder(
    input a,b,c,
    output sum,cout
    );
    
    wire m1,m2,m3;
    assign sum = a ^ b ^ c;
    //assign cout = ((a^b)&c)|(a&b);
    xor(m1,a,b);
    and(m2,m1,c);
    and(m3,a,b);
    or(cout,m2,m3); 
endmodule
  • 测试文件
`timescale 1ns / 1ps
module tb_adder();

reg a,b,c;
reg clk;
wire sum,cout;

initial
    begin
        #1
        a = 0;
        b = 0;
        c = 0;
        clk = 0;
    end
always #5 clk = ~clk;
always @(posedge clk)
    begin
        a = {$random} % 2;
        b = {$random} % 2;
        c = {$random} % 2;
    end
    adder u1(a,b,c,sum,cout);
endmodule
  • 仿真电路图
    在这里插入图片描述
  • 仿真波形
    在这里插入图片描述

全减器

  • 其真值表如下
    在这里插入图片描述
  • 其电路图如下
    在这里插入图片描述
  • 其表达式如下
    在这里插入图片描述在这里插入图片描述
  • 实现代码
`timescale 1ns / 1ps

module Full_subtracter(
    input a,b,c,
    output d,cin//本位想高位的借位
    );
    
    assign d = a ^ b ^ c;
    assign cin = (~a & (b^c)) | (b&c);
endmodule
  • 测试文件
`timescale 1ns / 1ps

module tb_subtracter();

reg a,b,c;
reg clk;
wire d, cin;

initial
    begin
        #1
        clk = 0;
        a = 0;
        b = 0;
        c = 0;
    end
    
always #5 clk = ~clk;
always @(posedge clk)
    begin
        a = {$random} % 2;
        b = {$random} % 2;
        c = {$random} % 2;
    end
    
    Full_subtracter u1(a, b, c, d, cin);
    
endmodule
  • 仿真电路图
    在这里插入图片描述
  • 仿真波形
    在这里插入图片描述

偶校验发生器

  • 其真值表如下
    在这里插入图片描述
  • 其电路图如下
    在这里插入图片描述
  • 其表达式如下
    在这里插入图片描述
  • 实现代码
`timescale 1ns / 1ps

module check(
    input a,b,c,d,
    output p
    );
    
    assign p = (c^d)^(a^b);
    
endmodule
  • 测试文件
`timescale 1ns / 1ps

module tb_check();

reg a,b,c,d;
reg clk;
wire p;

initial
    begin
        #1
        clk = 0;
        a = 0;
        b = 0;
        c = 0;
        d = 0; 
    end

always #5 clk = ~clk;
always @(posedge clk)
    begin
        a = {$random} % 2;
        b = {$random} % 2;
        c = {$random} % 2;
    end

check u1(a,b,c,d,p);

endmodule
  • 仿真电路图
    在这里插入图片描述
  • 仿真波形
    在这里插入图片描述

数据比较器

  • 其真值表如下
    在这里插入图片描述

  • 其电路图如下
    在这里插入图片描述

  • 其表达式如下
    在这里插入图片描述

  • 实现代码

`timescale 1ns / 1ps

module comparator(
    input a, b,
    output Fb, Fe, Fs
    );
    
    assign Fb = ~b & a;
    assign Fe = ~a & b;
    assign Fs = (a & b) | (~a & ~b);
      
endmodule
  • 测试文件
`timescale 1ns / 1ps

module tb_comparator();

reg a, b;
reg clk;
wire Fb, Fe, Fs;
initial
    begin
        #1
        clk = 0;
        a = 0;
        b = 0;
    end

always #5 clk = ~clk;
always @(posedge clk)
    begin
        a = {$random} % 2;
        b = {$random} % 2;
    end

comparator u1(a, b, Fb, Fe, Fs);

endmodule
  • 仿真电路图
    在这里插入图片描述
  • 仿真波形
    在这里插入图片描述

编码器

  • 其真值表如下
    在这里插入图片描述
  • 实现代码
`timescale 1ns / 1ps

module encoder(
    In,
    Out
);

input [7:0] In;
output [2:0] Out;
reg [2:0] Out;

always @(In)
    begin
        case(In)
            8'b0000_0001:Out = 3'b111;
            8'b0000_0010:Out = 3'b110;
            8'b0000_0100:Out = 3'b101;
            8'b0000_1000:Out = 3'b100;
            8'b0001_0000:Out = 3'b011;
            8'b0010_0000:Out = 3'b010;
            8'b0100_0000:Out = 3'b001;
            8'b1000_0000:Out = 3'b000;
            default: Out=3'bxxx;
        endcase
    end  
    
endmodule
  • 测试文件
//`timescale 1ns / 1ps

//module tb_encoder();


//endmodule
`timescale 1ns/1ns
`define clk_period 20

module tb_encoder();

reg 	[7:0]	In;
wire 	[2:0]	Out;
reg clk;

encoder tb_encoder(
	.In(In),
	.Out(Out)
);

initial clk = 1'b1;
always #`clk_period clk = ~clk;

initial begin
	
	In = 8'b0000_0001;
	#`clk_period;
	In = 8'b0000_0010;
	#`clk_period;
	In = 8'b0000_0100;
	#`clk_period;
	In = 8'b0000_1000;
	#`clk_period;
	In = 8'b0001_0000;
	#`clk_period;
	In = 8'b0010_0000;
	#`clk_period ;
	In = 8'b0100_0000;
	#`clk_period;
	In = 8'b1000_0000;
	#`clk_period;
	In = 8'b0000_0000;
	#`clk_period;
	
	$stop;
end

endmodule
  • 仿真电路图
    在这里插入图片描述
  • 仿真波形
    在这里插入图片描述
  • 小感悟

测试文件的写法还是不太会啊QWQ,后面还是会去好好研究一下测试文件怎么写

译码器

  • 其真值表如下
    在这里插入图片描述
  • 实现代码
module decoder(
	Y,
	S,
	A
);

output wire [7:0] Y;
input wire	[2:0] S;
input wire [2:0] A;

assign Y = (S==3'b100) ? ~(8'b000_001 << A) : 8'b0000_0000;

endmodule

  • 测试文件
`timescale 1ns/1ns

module tb_decoder;

wire [7:0] Y;
reg [2:0] S;
reg [2:0] A;

decoder tb_decoder(
	.Y(Y),
	.S(S),
	.A(A)
);

initial begin
	A = 3'b000;
	S = 3'b000;	
	#200;
	A = 3'b001;
	S = 3'b010;	
	#200;
	A = 3'b000;
	S = 3'b001;	
	#200;
	A = 3'b001;
	#200;
	A = 3'b010;
	#200;
	A = 3'b011;
	#200;
	A = 3'b100;
	#200 ;
	A = 3'b101;
	#200;
	A = 3'b110;
	#200;
	A = 3'b111;
	#200;
	A = 3'b000;
	#200;
	
	$stop;
end
endmodule
  • 仿真波形
  • 莫名其妙显示的是十进制,很难受,后续调整吧QWQ
    在这里插入图片描述

数据选择器(4选1)

  • 其真值表如下
    在这里插入图片描述
  • 其逻辑图如下
    在这里插入图片描述
  • 其表达式如下
    在这里插入图片描述
  • 实现代码
`timescale 1ns / 1ps

module mux(
    input D0, D1, D2, D3,
    input A0, A1,
    output Y
    );
    
    assign Y = ((D0 & ~A0 & ~A1)|(D1 & ~A0 & A1)|(D2 & A0 & ~A1)|(D3 & A0 & A1));
    
endmodule
  • 测试文件
`timescale 1ns / 1ps

module tb_mux();

reg D0, D1, D2, D3;
reg A0, A1;
reg clk;
wire Y;

initial
    begin
        #1
        clk = 0;
        A0 = 0;
        A1 = 0;
        D0 = 1;
        D1 = 1;
        D2 = 1;
        D3 = 1; 
    end
   
always #5 clk = ~clk;
always @(posedge clk)
    begin
        A0 = {$random} % 2;
        A1 = {$random} % 2;
        D0 = {$random} % 2;
        D1 = {$random} % 2;
        D2 = {$random} % 2;
        D3 = {$random} % 2;
    end
   
mux u1(D0, D1, D2, D3, A0, A1, Y);
endmodule
  • 仿真电路图
    在这里插入图片描述
  • 仿真波形
    在这里插入图片描述

多路分配器

  • 其真值表如下
    在这里插入图片描述
  • 实现代码
`timescale 1ns / 1ps

module selector(
    input D,
    input A0, A1,
    output Y0, Y1, Y2, Y3
    );
//    reg Y0, Y1, Y2, Y3;
//    initial
//        {Y0,Y1,Y2,Y3}=4'b1111;
//    always@(*)
//        case({A1,A0})
//            2'b00:begin
//                    Y0 = D; Y1=1'b1; Y2=1'b1; Y3=1'b1;
//                  end
//            2'b01:begin
//                    Y0 = 1'b1; Y1=D; Y2=1'b1; Y3=1'b1;
//                  end
//            2'b10:begin
//                    Y0 = 1'b1; Y1=1'b1; Y2=D; Y3=1'b1;
//                  end
//            2'b11:begin
//                    Y0 = 1'b1; Y1=1'b1; Y2=1'b1; Y3=D;
//                  end
//        endcase
        assign Y0=~A1 & ~A0 & D;
 	    assign Y1=~A1 &  A0 & D;
 	    assign Y2= A1 & ~A0 & D;
 	    assign Y3= A1 &  A0 & D;
endmodule
  • 测试文件
`timescale 1ns / 1ps

module tb_selector();

reg D;
reg A0, A1;
reg clk;
wire Y0, Y1, Y2, Y3;

initial
    begin
        #1
        clk = 0;
        D = 0;
        A0 = 0;
        A1 = 0;
    end

always #5 clk = ~clk;
always @(posedge clk)
    begin
        D = {$random} % 2;
        A0 = {$random} % 2;
        A1 = {$random} % 2;
    end
    
 selector u1(D, A0, A1, Y0, Y1, Y2, Y3);
 
endmodule

  • 仿真电路图
    在这里插入图片描述

  • 仿真波形
    在这里插入图片描述

  • 0
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值