当前位置: 首页 > article >正文

Verilog基础(四):组合逻辑

电路 (Circuits)

组合逻辑 (Combinational Login)

基础门电路
- Wire类型

实现如下电路:

wire

  • Module Declaraction
module top_module (
    input in,
    output out);
  • Solution
module top_module (
    input in,
    output out);
    
assign out =in;
endmodule
- 接地 – GND

实现如下电路:

  • Module Declaraction
module top_module (
    output out);
  • Solution
module top_module (
    output out);
assign out = 'b0;
endmodule
- 或非门 (NOR)

实现如下电路:

[外链图片转存中…(img-rrC5KOrq-1738668675073)]

  • Module Declaraction
module top_module (
    input in1,
    input in2,
    output out);
  • Solution
module top_module (
    input in1,
    input in2,
    output out);
    assign out = ~(in1|in2);
endmodule
- 其他的门

实现如下电路:

q4f

  • Module Declaraction
module top_module (
    input in1,
    input in2,
    output out);
  • Solution
module top_module (
    input in1,
    input in2,
    output out);
assign out = in1&~in2;
endmodule
- 两个门

实现如下电路:

q4g

  • Module Declaraction
module top_module (
    input in1,
    input in2,
    input in3,
    output out);
  • Solution
module top_module (
    input in1,
    input in2,
    input in3,
    output out);
 wire out1;
    
    assign out1 = ~(in1^in2);
    
assign out = in3^ out1;
endmodule
- 7420模块

创建如下电路:

  • Module Declaraction
module top_module ( 
    input p1a, p1b, p1c, p1d,
    output p1y,
    input p2a, p2b, p2c, p2d,
    output p2y );
  • Solution
module top_module ( 
    input p1a, p1b, p1c, p1d,
    output p1y,
    input p2a, p2b, p2c, p2d,
    output p2y );
    assign p1y = ~(p1a&p1b&p1c&p1d);
    assign p2y = ~(p2a&p2b&p2c&p2d);
endmodule
- 小练习 – Two-bit equality

若A==B则输出1,否则输出0

  • Module Declaraction
module top_module ( input [1:0] A, input [1:0] B, output z ); 
  • Solution
module top_module ( input [1:0] A, input [1:0] B, output z ); 
    assign z = ((A[1]==B[1])&&(A[0]==B[0]))?1:0;
endmodule
- 简单电路A

实现一个模块,具有z = (x^y) & x功能

  • Module Declaraction
module top_module (input x, input y, output z);
  • Solution
module top_module (input x, input y, output z);
    assign z = (x^y)&x;
endmodule
- 简单电路B

电路B可以通过以下模拟波形来描述:

[外链图片转存中…(img-8UTGCuab-1738668675074)]

  • Module Declaraction
module top_module ( input x, input y, output z );
  • Solution
module top_module ( input x, input y, output z );
    assign z = ~(x^y);
endmodule
- 组合电路AB

通过电路A,B构建如下电路:

[外链图片转存中…(img-XRsWORya-1738668675074)]

  • Module Declaraction
module top_module ( input x, input y, output z );
  • Solution
module top_module (input x, input y, output z);
    wire z1,z2,z3,z4,out1,out2;
    A ins1(x,y,z1);
    B ins2(x,y,z2);
    A ins3(x,y,z3);
    B ins4(x,y,z4);
    assign out1 = z1 | z2;
    assign out2 = z3 & z4;
    assign z = out1 ^ out2;
endmodule

module A(input x, input y, output z);
    assign z = (x^y) & x;
endmodule

module B ( input x, input y, output z );
    assign z = ~(x^y);
endmodule

- 恒温器

实现一个加热/冷却恒温器控制器.

执行一个电路,根据需要打开和关闭加热器、空调和鼓风机风扇.

恒温器可以处于两种模式之一:加热(mode=1)和冷却(mode=0).

在加热模式下,当加热器太冷(too_cold=1)时,打开加热器,但不要使用空调.在冷却模式下,当空调太热(too_hot=1)时打开空调,但不要打开加热器.

当加热器或空调打开时,也打开风扇使空气循环.

此外,即使加热器和空调关闭,用户也可以请求风扇打开(fan_on=1).

尝试只使用assign语句,以查看是否可以将问题描述转换为逻辑门集合.

  • Module Declaraction
module top_module (
    input too_cold,
    input too_hot,
    input mode,
    input fan_on,
    output heater,
    output aircon,
    output fan
); 
  • Solution
module top_module (
    input too_cold,
    input too_hot,
    input mode,
    input fan_on,
    output heater,
    output aircon,
    output fan
); 
    always @(*) begin
        if(fan_on == 1) begin
            fan = 1;
        end
        else begin
            fan = 0;
        end
        if(mode == 1) begin
            heater = mode;
            if(too_cold) begin
                heater = 1;
                fan = 1;
                aircon = 0;
            end
            else begin
                heater = 0;
                aircon = 0;
            end
        end
            else begin 
            if(too_hot) begin
                aircon = 1;
                fan = 1;
                heater = 0;
            end
            else begin
                aircon = 0;
                heater = 0;
            end
        end
    end
endmodule
- 3位计数器

计算3位vector中1的个数

  • Module Declaraction
module top_module( 
    input [2:0] in,
    output [1:0] out );
  • Solution
module top_module( 
    input [2:0] in,
    output [1:0] out );
    reg [1:0]num;
    integer i;
    always @(*) begin
        num = 0;
        for(i=0;i<3;i=i+1) begin
            if(in[i] == 1) begin
                num = num + 2'b1;          
            end
        end       
    end
    assign out = num;
endmodule
- 门与容器

给定4位vector,请给出每个位与其相临位之间的关系.

  • out_both: 判断相应位与其左临位是否均为1,不考虑in[3]

  • out_any: 判断相应位与其右临位是否含有’1’,不考虑in[0]

  • out_different: 判断相应位与其左临位是否不同,in[3[in[0]的左临位

  • Module Declaraction

module top_module( 
    input [3:0] in,
    output [2:0] out_both,
    output [3:1] out_any,
    output [3:0] out_different );
  • Solution
module top_module( 
    input [3:0] in,
    output [2:0] out_both,
    output [3:1] out_any,
    output [3:0] out_different );
    integer i;
    reg [2:0]both;
    reg [3:1]any;
    reg [3:0]different;
    always @(*) begin
        both = 0;
        any = 0;
        different = 0;
        for(i=0;i<3;i=i+1) begin
            if((in[i]&in[i+1]) == 1) begin
                both[i] = 1;
            end
        end
        for(i=1;i<4;i=i+1) begin
            if((in[i]|in[i-1]) == 1) begin
                any[i] = 1;
            end
        end
        for(i=0;i<4;i=i+1) begin
            if(i<3) begin
                if(in[i]^in[i+1]) begin
                    different[i] = 1;
                end
            end
            else begin 
                if(in[3]^in[0]) begin
                    different[3] = 1;
                end
            end
        end
    end
    assign out_both = both;
    assign out_any[3:1] = any[3:1];
    assign out_different = different;
endmodule
- 更长的数组

给定4位vector,请给出每个位与其相临位之间的关系.

  • out_both: 判断相应位与其左临位是否均为1,不考虑in[3]

  • out_any: 判断相应位与其右临位是否含有’1’,不考虑in[0]

  • out_different: 判断相应位与其左临位是否不同,in[3[in[0]的左临位

  • Module Declaraction

module top_module( 
    input [99:0] in,
    output [98:0] out_both,
    output [99:1] out_any,
    output [99:0] out_different );
  • Solution
module top_module (
	input [99:0] in,
	output [98:0] out_both,
	output [99:1] out_any,
	output [99:0] out_different
);

	// See gatesv for explanations.
	assign out_both = in & in[99:1];
	assign out_any = in[99:1] | in ;
	assign out_different = in ^ {in[0], in[99:1]};
	
endmodule

多路选择器(Multiplexers)
- 2选1多路选择器

创建一个1位宽的2对1多路选择器.当sel=0时,选择a;当sel=1时,选择b.

  • Module Declaraction
module top_module( 
    input a, b, sel,
    output out ); 	
  • Solution
module top_module (
	input a,
	input b,
	input sel,
	output out
);

	assign out = (sel & b) | (~sel & a);	// Mux expressed as AND and OR
	
	// Ternary operator is easier to read, especially if vectors are used:
	// assign out = sel ? b : a;
	
endmodule
- 2选1总线选择器

创建一个100位宽的2对1多路选择器.当sel=0时,选择a;当sel=1时,选择b.

  • Module Declaraction
module top_module( 
    input [99:0] a, b,
    input sel,
    output [99:0] out );
  • Solution
module top_module (
	input [99:0] a,
	input [99:0] b,
	input sel,
	output [99:0] out
);

	assign out = sel ? b : a;
	
	// The following doesn't work. Why?
	// assign out = (sel & b) | (~sel & a);
	
endmodule
- 9选1多路选择器

创建一个16位宽的9对1多路选择器.sel=0选择a,sel=1选择b等.对于未使用的情况(sel=9到15),将所有输出位设置为“1”.

  • Module Declaraction
module top_module( 
    input [15:0] a, b, c, d, e, f, g, h, i,
    input [3:0] sel,
    output [15:0] out );
  • Solution
module top_module (
	input [15:0] a,
	input [15:0] b,
	input [15:0] c,
	input [15:0] d,
	input [15:0] e,
	input [15:0] f,
	input [15:0] g,
	input [15:0] h,
	input [15:0] i,
	input [3:0] sel,
	output logic [15:0] out
);

	// Case statements can only be used inside procedural blocks (always block)
	// This is a combinational circuit, so use a combinational always @(*) block.
	always @(*) begin
		out = '1;		// '1 is a special literal syntax for a number with all bits set to 1.
						// '0, 'x, and 'z are also valid.
						// I prefer to assign a default value to 'out' instead of using a
						// default case.
		case (sel)
			4'h0: out = a;
			4'h1: out = b;
			4'h2: out = c;
			4'h3: out = d;
			4'h4: out = e;
			4'h5: out = f;
			4'h6: out = g;
			4'h7: out = h;
			4'h8: out = i;
		endcase
	end
	
endmodule
- 256选1多路选择器

创建一个1位宽、256对1的多路选择器.256个输入全部打包成一个256位输入vector.sel=0选择in[0],sel=1选择in[1],sel=2选择in[2]等等.

  • Module Declaraction
module top_module( 
    input [255:0] in,
    input [7:0] sel,
    output out );
  • Solution
module top_module (
	input [255:0] in,
	input [7:0] sel,
	output  out
);

	// Select one bit from vector in[]. The bit being selected can be variable.
	assign out = in[sel];
	
endmodule
- 256选1 4位选则器

创建一个4位宽、256对1的多路选择器.sel=0应选择in[3:0],sel=1选择in[7:4],sel=2选择in[11:8]等.

  • Module Declaraction
module top_module( 
    input [1023:0] in,
    input [7:0] sel,
    output [3:0] out );
  • Solution
module top_module( 
    input [1023:0] in,
    input [7:0] sel,
    output [3:0] out );
    reg [7:0]index;
    assign     out[3:0] = in[4*sel+:4];
endmodule

运算电路
- 半加器

创建一个半加器,对两个位做加法并输出结果与进位.

  • Module Declaraction
module top_module( 
    input a, b,
    output cout, sum );
  • Solution
module top_module( 
    input a, b,
    output cout, sum );
    assign {cout,sum} = a + b;
endmodule
- 全加器

创建一个全加器,对两位及进位做加法,输出结果与进位

  • Module Declaraction
module top_module( 
    input a, b, cin,
    output cout, sum );
  • Solution
module top_module( 
    input a, b, cin,
    output cout, sum );
    assign {cout,sum} = a + b + cin;
endmodule
- 3位加法器

创建一个三位全加器,把每位相加的进位都输出出来.

  • Module Declaraction
module top_module( 
    input [2:0] a, b,
    input cin,
    output [2:0] cout,
    output [2:0] sum );
  • Solution
module top_module( 
    input [2:0] a, b,
    input cin,
    output [2:0] cout,
    output [2:0] sum );
    FullAdder ins1(a[0],b[0],cin,cout[0],sum[0]);
    FullAdder ins2(a[1],b[1],cout[0],cout[1],sum[1]);
    FullAdder ins3(a[2],b[2],cout[1],cout[2],sum[2]);
endmodule

module FullAdder(
    input a, b, cin,
    output cout, sum
);
    assign {cout, sum} = a + b + cin;
endmodule
-adder练习

实现如下电路:

q4j.png

  • Module Declaraction
module top_module (
    input [3:0] x,
    input [3:0] y, 
    output [4:0] sum);
  • Solution
module top_module (
	input [3:0] x,
	input [3:0] y,
	output [4:0] sum
);

	// This circuit is a 4-bit ripple-carry adder with carry-out.
	assign sum = x+y;	// Verilog addition automatically produces the carry-out bit.

	// Verilog quirk: Even though the value of (x+y) includes the carry-out, (x+y) is still considered to be a 4-bit number (The max width of the two operands).
	// This is correct:
	// assign sum = (x+y);
	// But this is incorrect:
	// assign sum = {x+y};	// Concatenation operator: This discards the carry-out
endmodule
- 溢出检测

假设您有两个8位的补码,A[7:0]和B[7:0].这些数字加在一起产生s[7:0].还要计算是否发生了(有符号的)溢出.

  • Module Declaraction
module top_module (
    input [7:0] a,
    input [7:0] b,
    output [7:0] s,
    output overflow
); 
  • Solution
module top_module (
    input [7:0] a,
    input [7:0] b, 
    output [7:0] s,
    output overflow
);
    EightBitsAdder ins(a, b, s, overflow);
endmodule

module FullAdder(
    input a, b, cin,
    output sum, cout
);
    assign {cout, sum} = a + b + cin;
endmodule

module EightBitsAdder(
    input [7:0] x,
    input [7:0] y,
    output [7:0] s,
    output overflow
);
    wire [7:0] cout1;
    FullAdder ins0(x[0],y[0],0,s[0],cout1[0]);
    FullAdder ins1(x[1],y[1],cout1[0],s[1],cout1[1]);
    FullAdder ins2(x[2],y[2],cout1[1],s[2],cout1[2]);
    FullAdder ins3(x[3],y[3],cout1[2],s[3],cout1[3]);
    FullAdder ins4(x[4],y[4],cout1[3],s[4],cout1[4]);
    FullAdder ins5(x[5],y[5],cout1[4],s[5],cout1[5]);
    FullAdder ins6(x[6],y[6],cout1[5],s[6],cout1[6]);
    FullAdder ins7(x[7],y[7],cout1[6],s[7],cout1[7]);
    always @(*) begin
        if(cout1[7]^cout1[6]) begin
            overflow = 1;
        end
        else begin
            overflow = 0;
        end
    end
endmodule
- 100位加法器

创建一个100位加法器.

  • Module Declaraction
module top_module( 
    input [99:0] a, b,
    input cin,
    output cout,
    output [99:0] sum );
  • Solution
module top_module( 
    input [99:0] a, b,
    input cin,
    output cout,
    output [99:0] sum );
    assign {cout,sum} = a+b+cin;
endmodule
- BCD加法器

您将获得一个BCD(二进制编码十进制)一位加法器,名为BCD_fadd,它对两个BCD数字及进位做加法,产生一个和与进位.

module bcd_fadd {
    input [3:0] a,
    input [3:0] b,
    input     cin,
    output   cout,
    output [3:0] sum );

创建一个4BCD位加法器.

  • Module Declaraction
module top_module( 
    input [15:0] a, b,
    input cin,
    output cout,
    output [15:0] sum );
  • Solution
module top_module (
  input [15:0] a, b,
  input cin,
  output cout,
  output [15:0] sum
);

  wire [3:0] inter_cout;

  bcd_fadd bcd_fadd0_inst
  (
    .a(a[3:0]),
    .b(b[3:0]),
    .cin(cin),
    .cout(inter_cout[0]),
    .sum(sum[3:0])
  );

  genvar i;
  generate
    for (i = 1; i <=3; i = i + 1) begin: gen_bcd_adders
      bcd_fadd bcd_fadd_insts
      (
        .a(a[4*(i+1)-1 : 4*i]),
        .b(b[4*(i+1)-1 : 4*i]),
        .cin(inter_cout[i-1]),
        .cout(inter_cout[i]),
        .sum(sum[4*(i+1)-1 : 4*i])
      );
    end
  endgenerate

  assign cout = inter_cout[3];

endmodule


http://www.kler.cn/a/532600.html

相关文章:

  • Unity GetLocalizedString()失效问题
  • Kafka流式计算架构
  • Android学习19 -- 手搓App
  • MySQL锁详解
  • 结构体DMA串口接收比特错位
  • Hive:窗口函数(1)
  • 深度求索DeepSeek横空出世
  • Swift语言的文件操作
  • 【JavaScript】《JavaScript高级程序设计 (第4版) 》笔记-Chapter1-什么是 JavaScript
  • 基于遗传算法的64QAM星座图的最优概率整形matlab仿真,对比优化前后整形星座图和误码率
  • Sumatra PDF:小巧免费,满足多样阅读需求
  • Java中的单例模式(如果想知道Java中有关单例模式的知识,那么只看这一篇就足够了!)
  • 【自然语言处理(NLP)】生成词向量:GloVe(Global Vectors for Word Representation)原理及应用
  • 为AI聊天工具添加一个知识系统 之86 详细设计之27 数据处理:ETL
  • 爱陪伴:免费AI聊天陪伴软件的体验感受
  • Qt常用控件 多元素控件
  • 2.4学习内容
  • 代码随想录算法【Day36】
  • C++ 仿函数
  • babel-安装和使用
  • sort排序 计数排序 map set C++ 蓝桥杯
  • 实验13 JavaBean(二)
  • ROS-激光雷达-消息包格式-获取激光雷达数据-激光雷达避障
  • RabbitMQ深度探索:前置知识
  • 游戏引擎 Unity - Unity 打开项目、Unity Editor 添加简体中文语言包模块、Unity 项目设置为简体中文
  • 【435. 无重叠区间 中等】