一、按位运算与逻辑运算
与:&按位与;&&逻辑与;
或:| 按位或;|| 逻辑或;
非:~ 按位非;!逻辑非;
二、信号反转输出
使用按位拼接进行信号反转输出
三、奇偶校验
题目:现在需要对输入的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