【发布时间】:2018-05-22 03:26:42
【问题描述】:
我正在尝试进行的合成是在 GCD 算法有限状态机上进行的,该算法使用“如果更大则减法”方法工作。我将附上代码并尝试制定一个体面的问题。
module GCD_R (A,B,out,nrst,act,clk,fla_g);
input [31:0] A, B;
input clk, act, nrst;
output reg fla_g;
output reg [31:0] out;
reg [3:0] state, next_state;
reg [31:0] A_reg, B_reg, Aint_reg, Bint_reg, out_reg;//2 registers will keep intermediate numbers+out, and next numbers
parameter IDLE = 3'b001;
parameter ABIG = 3'b010;
parameter BBIG = 3'b100;
reg next_flag;
always @(*)
case (state)
IDLE: begin
$display("start");
if(act == 0) begin
A_reg = A; //A,B are wires that contain numbers from an external source
B_reg = B; //first assign to A_reg and B_reg
out_reg = 31'bx;
next_flag = 1'b0;
next_state = IDLE;
end
if(act == 1)
if(A_reg==0) begin
out_reg = B_reg;
next_flag = 1'b1; //testbench will know when we stopped
Aint_reg = A_reg; //taking care not to infer latches
Bint_reg = B_reg;
next_state = IDLE;
end
else if (B_reg==0) begin
out_reg = A_reg;
next_flag = 1'b1;
Aint_reg = A_reg; //taking care not to infer latches
Bint_reg = B_reg;
next_state = IDLE;
end
else if (A_reg >= B_reg) begin
out_reg = 31'bx;
next_flag = 1'b0;
Aint_reg = A_reg;
Bint_reg = B_reg;
next_state = ABIG;
end
else begin
out_reg = 4'bxxx;
next_flag = 1'b0;
Aint_reg = A_reg;
Bint_reg = B_reg;
next_state = BBIG;
end
else
begin
Aint_reg = A_reg;
Bint_reg = B_reg;
out_reg = 4'bxxx;
next_flag = 1'b0;
next_state = 4'bx;
end
end
ABIG: begin
if (A_reg==0 | B_reg==0) begin
out_reg = 31'bx;
next_flag = 1'b0;
next_state = IDLE;
Aint_reg = A_reg;
Bint_reg = B_reg;
end
else if (B_reg > A_reg) begin
out_reg = 31'bx;
next_flag = 1'b0;
next_state = BBIG;
Aint_reg = A_reg;
Bint_reg = B_reg;
end
else begin
out_reg = 31'bx;
next_flag = 1'b0;
next_state = ABIG;
Aint_reg = A_reg - B_reg;
Bint_reg = B_reg;
end
end
BBIG: begin
if (A_reg==0 | B_reg==0) begin
out_reg = 31'bx;
next_flag = 1'b0;
next_state = IDLE;
Aint_reg = A_reg;
Bint_reg = B_reg;
end
else if (A_reg > B_reg) begin
out_reg = 31'bx;
next_flag = 1'b0;
next_state = ABIG;
Aint_reg = A_reg;
Bint_reg = B_reg;
end
else begin
out_reg = 31'bx;
next_flag = 1'b0;
next_state = BBIG;
Aint_reg = A_reg;
Bint_reg = B_reg - A_reg;
end
end
default: begin
out_reg = 31'bx;
next_flag = 1'b0;
next_state = 4'bx;
Aint_reg = A_reg;
Bint_reg = B_reg;
$display("%t: State machine not initialized/n",$time);
end
endcase
always @(posedge clk or negedge nrst)
if (~nrst) begin
state <= IDLE;//we get the new values by resetting first
out <= 4'bx;//we don't want anything there at the reset
fla_g <= 1'b0;
end
else begin
state <= next_state;//otherwise, get the next state and the next registers to the intermediate ones
A_reg <= Aint_reg;// 2nd assign to A_reg and B_reg- that's the problem
B_reg <= Bint_reg;
out <= out_reg;
fla_g <= next_flag;
end
endmodule
首先,A 和 B 是通过外部源(测试台中的一些文本文件)接收要比较的数字列表的电线。
A_reg 和 B_reg 是中间寄存器,用于保存我们正在检查“if”语句的数字,
Aint_reg 和 Bint_reg 是寄存器,保存操作后寄存器的中间值,只在时钟上升时将它们发送回 A_reg 和 B_reg,
act 决定机器是否处于“开启”模式并可以执行算法
nrst 是负复位切换
问题是如何形成的:
您可以看到,在开头,有一个if(act == 0) 条件。放在那里是为了确保 A、B 线(从外部接收)处的值将进入那里的寄存器,而不是在我们处于 if(~nrst) 条件时将它们输入到顺序块中,因为进入动态没有意义值,而在复位。
这将我们带到当前的问题 - 我知道在顺序块和组合块中为 A 和 B 分配一个值是造成问题的原因,但我找不到替代方案。
附言我使用A_reg = A 的事实创建了闩锁,因为我没有分配给其他任何地方的A_reg,这是自编写以来的另一个问题Aint_reg = A_reg;
A_reg = Aint_reg;
满足闩锁不适合我。
p.s.2。我尝试在网站上查看类似的问题,但由于我对该主题缺乏足够的知识,我无法将我的问题与那里的问题联系起来
很高兴得到任何帮助,谢谢
编辑:我删除了 if(~nrst) 顺序块中的非阻塞分配,以免在组合块中多重分配 A_reg <= 0 和 A_reg = A,但多重分配问题仍然以某种方式困扰它
EDIT2: 似乎我忘记了一个基本的事情——不要在两个不同的“总是”块中分配给同一个变量,但我只是想不出一个足够好的解决方案来分配将 A、B 线连接到一个寄存器,而不是在顺序块中再次分配给它
【问题讨论】:
-
我会尝试提出一个体面的问题 - 不幸的是我没有看到一个:(
-
抱歉,我好像陷入了沉思。我想知道如何避免出现的多驱动器问题,因为我在组合块和顺序块中都为 A、B 分配了值。
标签: verilog synthesis greatest-common-divisor elaboration