Der folgende Code dient dazu, den Kehrwert einer Festkommazahl mit der Newton-Methode zu berechnen. Wenn start
aktiviert ist, tritt die Zustandsmaschine in den Schätzungszustand ein . Um einen Ausgangspunkt zu bekommen, fange ich bei 1/2^N an, wobei N der Index des höchstwertigen Bits ist. Es scheint in der Simulation gut zu funktionieren, aber wenn ich es synthetisiere, erhalte ich die folgende Warnung:
[Synth 8-5413] Mischung aus synchroner und asynchroner Steuerung für Register abs_n_reg im Modul qinv. ["/home/chase/vivado-workspace/FixedMath/FixedMath.srcs/sources_1/new/qinv.v":45]
Ich bin nicht wirklich sicher, warum ich das bekomme oder wie ich es beheben kann. abs_n_reg
ist der absolute Wert von n
. Ich setze nur seinen Wert von einem meiner Always-Blöcke.
module qinv(output reg signed [63:0] inv,
output reg ready = 1'b1,
input signed [63:0] n,
input start,
input clk);
reg sign;
reg [63:0] abs_n;
reg [63:0] cur_inv;
reg [63:0] next_inv;
localparam READY = 2'b00,
COMPUTE = 2'b01,
ESTIMATE = 2'b10;
reg [1:0] state = READY;
reg [1:0] next_state = READY;
wire [5:0] mb;
msb m(abs_n, mb);
always @(posedge clk or posedge start) begin
if(start && state == READY) begin
if(n[63] == 1'b1) begin
abs_n <= -n;
sign <= 1'b1;
end else begin
abs_n <= n;
sign <= 1'b0;
end
ready <= 1'b0;
cur_inv <= 64'b0;
state <= ESTIMATE;
end else begin
state <= next_state;
cur_inv <= next_inv;
if(state == COMPUTE && next_state == READY) begin
ready <= 1'b1;
if(sign) inv <= -next_inv;
else inv <= next_inv;
end
end
end
wire [63:0] p1, p2;
qmul m1(p1, abs_n, cur_inv);
reg [63:0] diff;
qmul m2(p2, diff, cur_inv);
always @* begin
next_inv = 0;
next_state = READY;
diff = 0;
if(state == ESTIMATE) begin
next_inv = {1'b1, 63'b0} >> mb;
next_state = COMPUTE;
end else if(state == COMPUTE) begin
diff = {30'b0, 2'b10, 32'b0} - p1;
next_inv = p2;
if(next_inv[63:1] == cur_inv[63:1])
next_state = READY;
else
next_state = COMPUTE;
end
end
endmodule
module msb(input [63:0] n, output reg [5:0] m);
integer i;
always @* begin
m = 0;
for(i = 0; i <= 63; i = i + 1)
if(n[i] == 1'b1) m = i;
end
endmodule
module div_test();
reg clk = 0;
always #5 clk = ~clk;
wire ready;
wire [63:0] out;
reg start = 0;
reg [63:0] in = {8'd207, 24'b0};
qinv d(out, ready, in, start, clk);
initial begin
#5 start = 1;
#10 start = 0;
#1000 $finish;
end
endmodule
Es ist genau wie die Warnung sagt, Sie mischen synchrone Logik mit asynchroner Logik.
Sie können nicht verwenden ... or posedge start ...
.
Chasep255
Paebbels
Chasep255
Paebbels
Greg
Paebbels
Chasep255