HDLbits刷题记录之Module addsub
题目给的电路图如下:
题目要求是实现一个加减器,即在a+b加上一个一位的sub,这个sub加进来的话,在两个地方起作用,当sub等于1的时候,表示是减法器,用32位宽的异或门对b进行异或,即可得到-b,这时候即a-b,后面a-b+1的这个1,将sub的1作为add16的进位输入,即可就实现了a-b+1。
实现步骤:先利用sub与b进行异或,之后,和前面的加法器一样。
代码如下:
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0] sum
);
//wire sub_16 = {16{sub}};
wire [0:0] cout_low,cout_high;
wire [15:0] sum_low, sum_high;
add16 add16_low( .a(a[15:0]), .b(b[15:0]^{16{sub}}), .cin(sub), .sum(sum_low), .cout(cout_low) );
add16 add16_hign( .a(a[31:16]), .b(b[31:16]^{16{sub}}), .cin(cout_low), .sum(sum_high), .cout(cout_high) );
assign sum = {sum_high,sum_low};
endmodule
总结思考:
在写的过程中,犯了一个错误,在开头声明wire的时候,使用了这句“wire sub_16 = {16{sub}};”,然后把这个sub_16与b进行异或,那这样的话,就相当于之后的sub_16的没有更新的,因此当sub=1的时候,结果与真实值不一样。所以更改为现在这个样子,这样每次就能更新这个sub_16。
本以为这个程序总能一遍过了吧,没想到路还远着呢。革命尚未成功,同志仍需努力。写着竟然有点喜欢Verilog语言了,虽然菜,但是热爱呀,可能这就是人菜瘾大的乐趣吧。