fpga基础语法(操作符汇总、奇偶检验、位运算、for语句简化代码、三输入数的大小比较、数据大小端转换)

目录

基础语法

操作符汇总

VL1 四选一多路器

VL2 异步复位的串联T触发器

VL3 奇偶校验

VL4 移位运算与乘法

VL5 位拆分与运算

VL6 多功能数据处理器

VL7 求两个数的差值

VL8 使用generate…for语句简化代码

VL9 使用子模块实现三输入数的大小比较

VL10 使用函数实现数据大小端转换


基础语法

操作符汇总

VL1 四选一多路器

思路1:case语句(4路以上用case更方便)

case(sel)
    2'b00: mux_out = d3;
    2'b01: mux_out = d2;
    2'b10: mux_out = d1;
    2'b11: mux_out = d0;
    default:mux_out = 2'bxx;
endcase

思路2:三目运算符

assign mux_out = (sel==2'd0)?d3:((sel==2'd1)?d2:((sel==2'd2)?d1:(d0)));

VL2 异步复位的串联T触发器

T触发器功能:

        当输入端T=0时,时钟脉冲到达触发器保持原态不变;

        当输入端T=1时,每来一个时钟脉冲触发器的状态翻转一次。

信号示意图:

VL3 奇偶校验

奇偶校验概念:

奇校验:就是让原有数据序列中(包括你要加上的一位)1的个数为奇数

1000110(0)你必须添0这样原来有3个1已经是奇数了所以你添上0之后1的个数还是奇数个。

偶校验:就是让原有数据序列中(包括你要加上的一位)1的个数为偶数

1000110(1)你就必须加1了这样原来有3个1要想1的个数为偶数就只能添1了。  

缺点:1位误码能检测出,2位及2位以上检测不出来,而且不能纠错。

思路:^a操作,可以检测a中的“1”是否为奇数;

           若a=100,^a=1^0^0=1,则1的数量为奇数,

           若a=1100,^a=1^1^0^0=0,则1的数量为偶数。

assign check_ji = ^bus; //每个位相异或,
assign check = (sel == 1) ? check_ji : ~check_ji;

VL4 移位运算与乘法

在硬件中进行乘除运算比较消耗资源,因此我们采用移位操作。

out <= d_reg + {d_reg ,1'b0};     //1+2=3

out <= d_reg + {d_reg,1'b0} + {d_reg,2'b0};     //1+2+4=7

out <= {d_reg,3'b0};      //8*d_reg

vivado仿真图:

VL5 位拆分与运算

注意:

        wire变量只能用于组合逻辑中的assign语句(组合逻辑的always语句中不能用);

        reg型变量用于时序逻辑中的always语句。

        所以要注意看 该题设定好了输出变量类型,意味着要用下图设计方法。 

VL6 多功能数据处理器

         if else即可完成

VL7 求两个数的差值

        if else即可完成,要注意if eles的赋值语句超过1个,就要加begin...end

VL8 使用generate…for语句简化代码

1、作用:generate…for是用于简化代码,

2、generate…for和for循环的区别:

        generate-for只针对于module、reg、net、assign、always、parameter、function、initial、task等语句或者模块,而for只针对于非例化的循环。

3、使用方式:

generate-for语句:
        1、generate-for语句必须用genvar关键字定义for的索引变量;
        2、for的内容必须用begin end块包起来,哪怕只有一句;
        3、begin end块必须起个名字。

        在开始仿真前,仿真器会对生成块中代码进行确立展开,展开后的仿真代码中生成变量genvar不复存在。

 4、举例模板:

 5、本题实现代码

VL9 使用子模块实现三输入数的大小比较

思路:ab比较,可得min_ab,再用min_ab和c比较,可得abc的最小值min_abc。

注意:t1时刻进行ab比较,t2时刻min_ab和c比较。但是有个问题,t2时刻c和t1时刻的c不一样。所以我们要给c延迟一个clk,加一个d触发器即可。

设计代码

`timescale 1ns/1ns

module main_mod(
	input clk,
	input rst_n,
	input [7:0]a,
	input [7:0]b,
	input [7:0]c,
	output [7:0]d
);

wire [7:0] min_ab;
reg [7:0] c_reg;

//给c加寄存器延迟一个clk
always @(posedge clk or negedge rst_n)begin
	if(!rst_n)
		c_reg <= 8'b0;
	else 
		c_reg <= c;
end

//先得到ab中的最小值min_ab 
minare u1(
		.clk(clk),
		.rst_n(rst_n),		
		.x_1(a),	
		.x_2(b),	
		.y(min_ab)	
	);

//再得到min_ab和c中的最小值d
minare u2(
		.clk(clk),
		.rst_n(rst_n),		
		.x_1(min_ab),	
		.x_2(c_reg),		//不能直接和c比较,因为ab的比较已经消耗了1个clk
		.y(d)				//此刻的c是下个时刻c,所以会出错。
	);

endmodule

module minare(
	input clk,
	input rst_n,
	input [7:0] x_1,
	input [7:0] x_2,
	output reg [7:0] y
);

always @(posedge clk or negedge rst_n)begin
	if(!rst_n)
		y <= 8'b0;
	else if(x_1 <= x_2)
		y <= x_1;
	else
		y <= x_2;
end

endmodule

VL10 使用函数实现数据大小端转换

        题目:请用函数实现一个4bit数据大小端转换的功能。实现对两个不同的输入分别转换并输出。

        在数字芯片设计中,经常把实现特定功能的模块编写成函数function,在需要的时候再在主模块中调用,以提高代码的复用性和提高设计的层次,方便后续的修改。    

大端小端区别:  

    大端:高字节数据存储在低地址。小端:低字节数据存储在低地址。

    在verilog中,是以比特为单位,例如十进制8,小端是1000,大端是0001。

    在c语言中,是以字节为单位,例如16进制1234,小端存储是3412,大端存储1234。

function和task的区别:

(1)任务能调用任务和函数,但是函数只能调用函数,不能调用任务;

(2)任务可以描述组合逻辑和时序逻辑,可以有时延;函数只能描述组合逻辑,仿真时延为0;

(3)任务可以有任意多个各种类型的输入;函数只能有input端口的输入参数,且至少输入一个参数;

(4)任务可以没有返回值;函数必须有一个返回值;

在定义task任务时,有下列六点需要注意: 
(1)在第一行“task”语句中不能列出端口名称; 
(2)任务的输入、输出端口和双向端口数量不受限制,甚至可以没有输入、输出以及
双向端口。 
(3)在任务定义的描述语句中,可以使用出现不可综合操作符合语句(使用最为频繁
的就是延迟控制语句) ,但这样会造成该任务不可综合。 
(4)在任务中可以调用其他的任务或函数,也可以调用自身。 
(5)在任务定义结构内不能出现 initial和 always过程块。 
(6)在任务定义中可以出现“disable 中止语句” ,将中断正在执行的任务,但其是不
可综合的。当任务被中断后,程序流程将返回到调用任务的地方继续向下执行。

参考来源:verilog中的task用法

设计代码

module function_mod(
	input [3:0]a,
	input [3:0]b,
	
	output [3:0]c,
	output [3:0]d
);

assign c = data_reverse(a);
assign d = data_reverse(b);

function [3:0] data_reverse;	//函数名
	input [3:0] data_in;	//输入变量
	begin
		data_reverse[0] = data_in[3];
		data_reverse[1] = data_in[2];
		data_reverse[2] = data_in[1];
		data_reverse[3] = data_in[0];
	end
endfunction

endmodule

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

内有小猪卖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值