时序是比较蛋疼的一个东西,我为了写这个调了2天,主要在于<=非阻塞赋值符号的合理使用和对状态的理解,切忌不可用C语言的执行过程去理解
<=
a<=b
c<=a
则c=a对嘛?
不对c=上一个状态的a
At = B (t-1)
Ct = A (t-1)
然后这两句的执行顺序如何?
并行。
搞明白这个 就可以针对很多bug做修改了
- 要多考虑状态的转移 每个状态做每个状态的事情 考虑可能被遗漏的状态 消除不确定的状态 比如赋初值的时候 每个涉及到的值都给他赋值一下
/*
实验:4位乘法器
目标:按理论课所讲的乘法器原理,设计4位整数乘法器。
输入:
开 关:左右4位分别代表4位二进制被乘数与乘数。
按 钮:最左:正常/按下分别对应:无符号乘法/补码乘法。
输出:
发光管:如果用到加法器,发光管自左至右显示:SF、CF、OF、ZF、PF。否则自定
数码管:数码管自左至右分别以十六进制显示:被乘数、乘数、积高4位、积低4位。
考虑1:可考虑阵列乘法器。
*/
module mul4b(
input clk,
input[3:0] A,
input[3:0] B,
input Ctrl,
output reg[15:0]HEX
);
reg[7:0] S;
reg[7:0] T;
// reg[7:0] u_ int,s_int;
reg state;
reg [3:0]B_reg;
reg [2:0] cnt;
//组合逻辑
//assign S = {4'b0000,{4{B[0]}}&A}+{3'b000,{4{B[1]}}&A,1'b0}+{2'b00,{4{B[2]}}&A,2'b00}+{1'b0,{4{B[3]}}&A,3'b000};
//时序逻辑
always @(posedge clk) begin
case(state)
1'b0:begin //initial
B_reg <= B;
S <= 8'b0000_0000;
T <= {4'b0000,A};
cnt <= 3'b000;
state <= 1'b1;
end
1'b1:begin
if(cnt <= 3'b011) begin
if(B_reg[0]==1'b1) begin
S <= S + T;
end
else begin
S <= S;
end
B_reg <= B_reg>>1;
T <= T<<1;
cnt <= cnt + 3'b001;
end
else begin
HEX <= {A,B,S};
state <= 1'b0;
end
end
default:;
endcase
end
endmodule