2024年5月

本文介绍了Verilog语言中的逻辑操作、使用wire和reg进行赋值的方法,包括always语句、加法器设计、模块例化、选择器、阻塞和非阻塞赋值,以及case、generate、向量比较和十六进制表示等内容。
摘要由CSDN通过智能技术生成

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

5.5、verilog

逻辑操作符如果一个操作数不为 0,它等价于逻辑 1;如果一个操作数等于 0,它等价于逻辑 0。

5.6、verilog

1.使用wire对reg赋值

如果reg型变量做赋值的左值,那么只有被驱动时才能接收到右值的赋值,具体方式可以使用always语句,将右值放入敏感列表中

//HDLBits-Vector3
module top_module (
    input [4:0] a, b, c, d, e, f,
    output [7:0] w, x, y, z );//

    reg [31:0] m;
    always@(a or b or c or d or e or f)//此处使用always语句进行对reg的赋值
        begin
			m<={a,b,c,d,e,f,2'b11};
        end
    assign z=m[7:0];
    assign y=m[15:8];
    assign x=m[23:16];
    assign w=m[31:24];
endmodule
//除此之外也可以采用拼接的方式实现
module top_module (
    input [4:0] a, b, c, d, e, f,
    output [7:0] w, x, y, z );//

    assign z={e[0],f,2'b11};
    assign y={d[3:0],e[4:1]};
    assign x={b[1:0],c,d[4]};
    assign w={a,b[4:2]};
endmodule

2.使用拼接运算符

对于被拼接运算符拼接的内容,如果是重复变量或者重复常量的拼接需要加两层拼接运算符

HDLBits-Vector4
module top_module (
    input [7:0] in,
    output [31:0] out );//
    assign out={{24{in[7]}},in};//in的拼接运算符可加可不加
endmodule


5.7 verilog

1.加法器

1.基本加法器

加法器1

2.低延迟加法器

加法器2

3.加减法器

在这里插入图片描述
sub为0,实现加法器功能
sub为1,实现减法器功能,异或门和1运算实现取反,在sub作为cin输入,取反加一为减法运算

2.模块例化

例化
把端口(包括输入输出)作为研究对象,左侧为输入,可用reg或者wire,右侧为输出,因为要实时反应右侧的变化一定为wire
目前来看,如果仅要求右侧输出随左侧输入变化,在组合逻辑下使用reg作为右侧同样可行(吗)。

3.选择器

多选的选择器可以使用case语句
二选一为特殊情况,采取三元运算符简化

4.阻塞和非阻塞赋值

阻塞赋值为=,用于组合逻辑中,包括always@(*)
非阻塞赋值为<=,用于时序逻辑中,包括always@(possedge clk)
assign 赋值不用于always块中

5.8 verilog

1.case,casex和casez

case为全等比较,casez忽略z位,casex忽略z位和x位

2.归约操作符

归约操作符为单目运算符,对目标向量进行逐位运算

& a[3:0]     // AND: a[3]&a[2]&a[1]&a[0].

5.9 MOLE

5.10

1.使用generate for实现实例化

//HDLBits-Adder100i
//for循环实例化100个1bit全加器
/*
1.generate例化可以使用对应的genvar变量
2.generate for语句要在begin后为循环实例命名
3.for循环中实例化可以使用相同的名字,实际上循环实例化后命名为
addloop[0] myadd,addloop[1] myadd...
*/

module top_module( 
    input [99:0] a, b,
    input cin,
    output [99:0] cout,
    output [99:0] sum );
    
    genvar i;
    generate
        for(i=0;i<100;i=i+1)
            begin:addloop
                if(i==0)
                    add myadd(.a(a[i]),.b(b[i]),.cin(cin),.sum(sum[i]),.cout(cout[i]));
                else
                    add myadd(.a(a[i]),.b(b[i]),.cin(cout[i-1]),.sum(sum[i]),.cout(cout[i]));
            end
    endgenerate

endmodule

module add(input a,b,
          input cin,
          output sum,
          output cout);
    assign sum=a^b^cin;
    assign cout=(a&b)|(a&cin)|(b&cin);
endmodule

2.向量之间比较

向量之间按位比较可以不使用for循环而是直接按位比较

HDLBits-Gatesv
module top_module (
	input [3:0] in,
	output [2:0] out_both,
	output [3:1] out_any,
	output [3:0] out_different
);

	// Use bitwise operators and part-select to do the entire calculation in one line of code
	// in[3:1] is this vector:   					 in[3]  in[2]  in[1]
	// in[2:0] is this vector:   					 in[2]  in[1]  in[0]
	// Bitwise-OR produces a 3 bit vector.			   |      |      |
	// Assign this 3-bit result to out_any[3:1]:	o_a[3] o_a[2] o_a[1]

	// Thus, each output bit is the OR of the input bit and its neighbour to the right:
	// e.g., out_any[1] = in[1] | in[0];	
	// Notice how this works even for long vectors.
	assign out_any = in[3:1] | in[2:0];

	assign out_both = in[2:0] & in[3:1];
	
	// XOR 'in' with a vector that is 'in' rotated to the right by 1 position: {in[0], in[3:1]}
	// The rotation is accomplished by using part selects[] and the concatenation operator{}.
	assign out_different = in ^ {in[0], in[3:1]};
	
endmodule

3.三元运算符

三元运算符同样具有按位操作的能力,可以处理向量

4.十六进制表示

在使用十六进制表示时,如fff应该使用12’hfff而不是3’hfff表示

5.全1表示方法

reg [15:0] j;
j='1;
j=~0;
j=-1;//补码表示方法

5.11 MOLE

5.12 verilog

例化过程中尽量不要缺少输入输出变量

1,实现一个100bit加法器

//HDLBits-Adder100
module top_module( 
    input [99:0] a, b,
    input cin,
    output cout,
    output [99:0] sum );
    assign {cout,sum}=a+b+cin;
endmodule

首先,cin和a位数不同,不同位数的向量之间可以相加
其次,使用{cout,sum}将多个输出拼接为向量进行同时赋值

2.JK触发器

一种简明易懂的JK触发器verilog描述方法

//边沿JK触发器
module jk_trigger(clk, j, k, q);
 
input clk, j, k;
output q;
reg q;
wire qb;
always@(posedge clk)       //时钟上升沿到来时,判断jk的值
begin
	case({j,k})
	2'b00: q <= q;       //如果{j,k}=00,则触发器处于保持状态
	2'b01: q <= 1'b0;    //如果{j,k}=01,则触发器置1
	2'b10: q <= 1'b1;    //同理10,清零
	2'b11: q <= ~q;      //11,翻转
	default: q <= q;
	endcase
end
 
assign qb = ~q;
 
endmodule

我写的狗屎

module top_module (
    input clk,
    input j,
    input k,
    output Q); 
    always@(posedge clk)begin
        Q<=(j^k)?j:(j?~Q:Q);
    end
endmodule

5.13 verilog

5.14verilog

1.复位

能使用同步复位的情况尽量不不使用异步复位,以下代码若使用异步复位会因为某些原因出现错误

module top_module (
    input clk,
    input reset,
    input [31:0] in,
    output [31:0] out
);
    reg [31:0] lastin;
    always@(posedge clk)begin//  异步复位  always@(posedge clk,posedge reset)begin
        if(reset)
            out<=32'b0;
        else 
            out<=~in&lastin|out;
        lastin<=in;
    end

endmodule

5.15 MOLE

5.16 verilog

1.关于模块输出

可以直接用赋值的方法控制模块输出

//Count15-HDLBits
//我的解法,兜了个圈子
module top_module (
    input clk,
    input reset,      // Synchronous active-high reset
    output [3:0] q);
    reg [3:0]cnt;
    always@(posedge clk)begin
        if(reset)
            cnt<=0;
        else
            cnt<=cnt+1;
    end
    assign q=cnt;

endmodule

//答案解法
module top_module(
	input clk,
	input reset,
	output reg [3:0] q);
	
	always @(posedge clk)
		if (reset)
			q <= 0;
		else
			q <= q+1;		// Because q is 4 bits, it rolls over from 15 -> 0.
		// If you want a counter that counts a range different from 0 to (2^n)-1, 
		// then you need to add another rule to reset q to 0 when roll-over should occur.
	
endmodule

2.复位

可以采用将多种复位条件使用||并列在同意条件语句中

module top_module(
	input clk,
	input reset,
	output reg [3:0] q);
	
	always @(posedge clk)
		if (reset || q == 9)	// 使用逻辑或
			q <= 0;
		else
			q <= q+1;
	
endmodule

5.21 verilog

1.模块例化

模块例化的输入可以连接
1.topmodule的input
2.topmodule的output
3.直接填表达式

HDLbits-Exams/ece241 2014 q7a
module top_module (
    input clk,
    input reset,
    input enable,
    output [3:0] Q,
    output c_enable,
    output c_load,
    output [3:0] c_d
); //
    assign c_enable=enable;
    assign c_load=reset|(Q==4'b1100&enable);
    assign c_d=1;
    wire myload;
    count4 mycnt(.clk(clk),.enable(enable),.load(myload),.d(1),.Q(Q));
    //这里load可以直接连c_load,c_load作为output直接连上端口虽然有点反直觉但是是可行的
    //count4 mycnt(.clk(clk),.enable(enable),.load(reset|(Q==4'b1100&enable)),.d(1),.Q(Q)); 端口连接表达式
endmodule
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值