FPGA-牛客网-Verilog快速入门1

一、按位运算与逻辑运算

与:&按位与;&&逻辑与;

或:| 按位或;|| 逻辑或;

非:~ 按位非;!逻辑非;

二、信号反转输出

使用按位拼接进行信号反转输出

三、奇偶校验

题目:现在需要对输入的32位数据进行奇偶校验,根据sel输出校验结果(1输出奇校验,0输出偶校验)

理解:奇偶校验指的是一个数的二进制有多少个1,奇数个1结果为1,偶数个1结果为0,主要是运用异或(XOR来完成校验)。

在Verilog中,^运算符作为单目运算符时的功能是"按位异或",作为双目运算符时的功能是"异或"。当data_in是一个8 bit,的数据时,^data_in = data_in[0] ^ data_in[1] ^ data_in[2] ^ data_in[3] ^ data_in[4] ^ data_in[5] ^ data_in[6] ^ data_in[7],简言之,就是^bus,就是检查bus中1的个数是否是成对的,如果成队,那就是为0,也就是偶校验,所以奇校验刚好取反。

`timescale 1ns/1ns
module odd_sel(
input [31:0] bus,
input sel,
output check
);
//*************code***********//
wire check_tmp;

    assign check_tmp = ^bus;
    
    reg check_reg;
    always @ (*) begin
        if(sel) begin
            check_reg = check_tmp;
        end
        else begin
            check_reg = ~check_tmp;
        end 
    end 
    
    assign check = check_reg;

//*************code***********//
endmodule

四、移位运算与乘法

在硬件中进行乘除法运算是比较消耗资源的一种方法,想要在不影响延迟并尽量减少资源消耗,必须从硬件的特点上进行设计。根据寄存器的原理,由于是二进制,所以进位和退位为x2或者/2,同样除7可以使用进位3然后减去本身的做法,这样就将乘除法运算转化为位运算,这是一种比较简单的整数运算处理。

`timescale 1ns/1ns
module multi_sel(
input [7:0]d ,
input clk,
input rst,
output reg input_grant,
output reg [10:0]out
);
//*************code***********//
reg [1:0]cnt;
reg [7:0]d_temp;
//建立一个计数器
always@(posedge clk or negedge rst)begin
    if(rst==1'b0)begin
        cnt<=2'd0;
    end
    else if(cnt==2'd3)begin
        cnt<=2'd0;
    end
    else begin
        cnt<=cnt+1'b1;
    end
end

//写一个数据寄存器以及开始的标志位
always@(posedge clk or negedge rst)begin
    if(rst==1'b0)begin
        d_temp<=8'd0;
        input_grant<=1'b0;
    end
    else if(cnt==2'd0)begin
        d_temp<=d;
        input_grant<=1'b1;
    end
    else begin
        d_temp<=d_temp;
        input_grant<=1'b0;
    end
end
//乘法运算
always@(posedge clk or negedge rst)begin
    if(rst==1'b0)begin
        out<=11'd0;
    end
    else case(cnt)
    //原始
    2'd0:begin
        out <= d;
    end
    //乘3
    2'd1:begin
        out <= (d_temp<<2)-d_temp;
    end
    //乘7
    2'd2:begin
        out <= (d_temp<<3)-d_temp;
    end
    //乘8
    2'd3:begin
        out <= (d_temp<<3);
    end
    default:begin
        out<=11'd0;
    end
    endcase
end
//*************code***********//
endmodule

 这里需要注意的是看乘法运算在二进制中如何变为移位运算,节省硬件的计算资源。

五、位拆分与运算

`timescale 1ns/1ns

module data_cal(
input clk,
input rst,
input [15:0]d,
input [1:0]sel,

output [4:0]out,
output validout
);
//*************code***********//
reg [1:0]cnt;
reg [15:0]d_temp;
reg [4:0]out_temp;

assign validout = (sel == 2'd0) ? 0 : 1;

always@(posedge clk or negedge rst)begin
    if (rst==1'b0)begin
        out_temp<=5'd0;
        d_temp<=16'd0;
    end
    else 
    case(sel)
    2'd0:begin
        out_temp<=16'd0;
        d_temp<=d;
    end
    2'd1:begin
        out_temp<=d_temp[3:0]+d_temp[7:4];
    end
    2'd2:begin
        out_temp<=d_temp[3:0]+d_temp[11:8];
    end
    2'd3:begin
        out_temp<=d_temp[3:0]+d_temp[15:12];
    end
    default:begin
        out_temp<=16'd0;
    end
    endcase
end

assign out = out_temp;
//*************code***********//
endmodule

六、多功能数据处理器

`timescale 1ns/1ns
module data_select(
	input clk,
	input rst_n,
	input signed[7:0]a,//有符号数,最高位为符号位
	input signed[7:0]b,
	input [1:0]select,
	output reg signed [8:0]c
);

always@(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
	c<=9'd0;
end
else case(select)
	2'd0:begin
	c<={a[7],a};
	end
	2'd1:begin
	c<={b[7],b};
	end
	2'd2:begin
	c<={a[7],a}+{b[7],b};
	end
	2'd3:begin
	c<={a[7],a}-{b[7],b};
	end
endcase

end

endmodule

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值