Ich entwerfe eine Binär-zu-BCD-Konverter-Logikschaltung zur Implementierung auf Xilinx Spartan 6 FPGAs, und ich habe während der Synthese eine Warnung, die so aussieht:
WARNING:Xst:2170 - Unit binary_to_bcd_converter : the following signal(s) form a combinatorial loop:
start_conversion_mmx_out,
GND_1_o_shift_reg_next[11]_LessThan_9_o_mmx_out1,
GND_1_o_shift_reg_next[11]_LessThan_9_o,
shift_reg_next<1>,
GND_1_o_shift_reg_next[19]_LessThan_12_o_mmx_out1,
n0067<0>,
n0067<9>,
shift_reg_next<10>,
n0065<9>,
n0065<0>.
Ich versuche zu verstehen, wie sich diese Warnung in mein Design übersetzt, indem ich versuche, das RTL-Schema zu lesen, aber ich kann keinen vernünftigen Weg finden, dies zu tun. Hier verstehe ich einfach einiges nicht:
Also meine Frage ist:
EDIT: Hier ist mein Code für den Binär-zu-BCD-Konverter
module binary_to_bcd_converter(
// signals
input wire clk,
input wire reset,
input wire start_conversion,
output reg end_of_conversion,
// data
input wire [7:0] binary_data,
output reg [11:0] bcd_data
);
// state declarations
localparam
idle = 1'b0,
converting = 1'b1;
// signal declarations
reg state_reg, state_next;
reg [11:0] bcd_data_next;
reg [19:0] shift_reg,shift_reg_next;
reg [2:0] count,count_next;
reg end_of_conversion_next;
// state_updation_logic
always @(posedge(clk),posedge(reset)) begin
if(reset) begin
state_reg = idle;
bcd_data = 12'b0;
shift_reg = 20'b0;
count = 4'b0;
end_of_conversion = 1'b0;
end else begin
// the last activity should be the
// synchronous activity
state_reg = state_next;
bcd_data = bcd_data_next;
shift_reg = shift_reg_next;
count = count_next;
end_of_conversion = end_of_conversion_next;
end
end
always @* begin
// in idle state
if(state_reg == idle) begin
// moore signals
count_next <= 4'b0;
bcd_data_next <= bcd_data;
end_of_conversion_next <= 1'b0;
// mealey signals
if(start_conversion) begin
state_next <= converting;
shift_reg_next = {12'b0,binary_data};
end else begin
state_next <= idle;
shift_reg_next = 20'b0;
end
// in converting state
end else if(state_reg == converting) begin
if(count == 7) begin
count_next <= 4'b0;
bcd_data_next <= shift_reg[19:8];
state_next <= idle;
end_of_conversion_next <= 1'b1;
shift_reg_next = 20'b0;
end else begin
count_next <= count + 1;
bcd_data_next <= bcd_data;
state_next <= converting;
end_of_conversion_next <= 1'b0;
if(shift_reg[10:7] > 4'd4) begin
if(shift_reg[14:11] > 4'd4) begin
if(shift_reg[18:15] > 4'd4) begin
shift_reg_next = {shift_reg[18:0],1'b0} + 20'b0011_0011_0011_0000_0000;
end else begin
shift_reg_next = {shift_reg[18:0],1'b0} + 10'b0000_0011_0011_0000_0000;
end
end else begin
if(shift_reg[18:15] > 4'd4) begin
shift_reg_next = {shift_reg[18:0],1'b0} + 20'b0011_0000_0011_0000_0000;
end else begin
shift_reg_next = {shift_reg[18:0],1'b0} + 10'b0000_0000_0011_0000_0000;
end
end else begin
if(shift_reg[14:11] > 4'd4) begin
if(shift_reg[18:15] > 4'd4) begin
shift_reg_next = {shift_reg[18:0],1'b0} + 20'b0011_0011_0000_0000_0000;
end else begin
shift_reg_next = {shift_reg[18:0],1'b0} + 10'b0000_0011_0000_0000_0000;
end
end else begin
if(shift_reg[18:15] > 4'd4) begin
shift_reg_next = {shift_reg[18:0],1'b0} + 20'b0011_0000_0000_0000_0000;
end else begin
shift_reg_next = {shift_reg[18:0],1'b0} + 10'b0000_0000_0000_0000_0000;
end
end
end
end
end
end else begin
count_next <= count;
bcd_data_next <= bcd_data;
end_of_conversion_next <= end_of_conversion;
count_next <= count;
shift_reg_next = shift_reg;
end
end
endmodule
In einem kombinatorischen Block ( always @* begin ...
) können Sie keine Zuweisungsanweisung haben, in der das gleiche Signal auf der linken und rechten Seite erscheint.
Sie haben beispielsweise mehrere Instanzen von:
if (/* some condition */) begin
shift_reg_next = shift_reg_next + 20'b0000_0000_0011_00000000;
end
Das ist eine kombinatorische Schleife. Wenn die Bedingung wahr ist, wird die Addition so schnell wie möglich immer und immer wieder ausgeführt. Dies ist nicht synthetisierbar, und die Tools beschweren sich darüber.
Sie müssen diesen Block mit einem feinen Kamm durchgehen und sicherstellen, dass sich der Satz von Eingangssignalen (alles auf der rechten Seite von Zuweisungen) vollständig von dem Satz von Ausgangssignalen (auf der linken Seite von Zuweisungen) unterscheidet.
David Tweed
start_conversion_mmx_out
odershift_reg_next
. Wenn Ihre ursprüngliche Quelle ein Schaltplan ist und viele unbenannte Drähte enthält, sollten Sie versuchen, ihnen aussagekräftige Namen hinzuzufügen, und prüfen, ob einer dieser Namen in diesem Bericht auftaucht.Eisenstein
Martin Zabel
Eisenstein