El siguiente código es tomar el recíproco de un número de punto fijo usando el método de Newton. Cuando start
se afirma, la máquina de estado entra en el estado de estimación . Para obtener un punto de partida, empiezo en 1/2^N, donde N es el índice del bit más significativo. Parece funcionar bien en la simulación, pero cuando lo sintetizo, aparece la siguiente advertencia:
[Synth 8-5413] Combinación de control sincrónico y asincrónico para el registro abs_n_reg en el módulo qinv. ["/home/chase/vivado-workspace/FixedMath/FixedMath.srcs/sources_1/new/qinv.v":45]
No estoy muy seguro de por qué estoy recibiendo esto o cómo solucionarlo. abs_n_reg
es el valor absoluto de n
. Solo estoy configurando su valor desde uno de mis bloques siempre.
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 exactamente como dice la advertencia, está mezclando lógica síncrona con lógica asíncrona.
No puedes usar ... or posedge start ...
.
persecucion255
Paebbels
persecucion255
Paebbels
greg
Paebbels
persecucion255