дизайн загрузки ошибок verilog modelsim (калькулятор)

#verilog #calculator #modelsim #test-bench

#verilog #калькулятор #modelsim #испытательный стенд

Вопрос:

здравствуйте, у меня проблема с запуском modelsim. я создаю 16-разрядный калькулятор, который может работать с вычислением сложения, вычитания, кратности, деления. вход и выход-это 20-битный bcd-код. Для расчета сначала я преобразую входной bcd-код в двоичный. После двоичного вычисления я преобразую двоичный код в код bcd. я не должен использовать *’, ‘/’, ‘%’, ‘lt;lt;’, ‘gt;lt;’, ‘gt;gt;’, ‘lt;’, ‘gt;gt;lt;lt;lt;’, и ‘gt;lt;’, и ‘gt;gt;lt;’, и ‘gt;gt;gt;’ в коде verilog. это мой код калькулятора

 module calculator_p( input wire [3:0] a, input wire clk, input wire rst, //key0 input wire result, //sw9 input wire in_set , //sw4 input wire [1:0] selectmode, //sw6-5 input wire mode, //sw7 1(-) 0( ) output reg ov, //ledr9 output reg [19:0] in_1, //first_input output reg [19:0] in_2, //second_input  output reg [19:0] out, //final output output reg [19:0] m1, //add_sub result output reg [19:0] m2, //multiple result output reg [11:0] m3,  output reg [15:0] remain, //divide calculation remain //division result output wire [6:0] digit4, output wire [6:0] digit3, output wire [6:0] digit2, output wire [6:0] digit1,  output wire [6:0] digit0  );  reg [15:0] cal1; //for calculation first binary variable reg [15:0] cal2; //for calculation second binary variable reg [7:0] cal2_1; //for divide calculation binary second variable reg [15:0] cal3; //add, sub, multiple calculation binary result reg [7:0] cal3_1; //divide calculation binary result   always @ (posedge clk, negedge rst, negedge result)  begin  if (rst==1'b0) begin in_1lt;=20'b0;  in_2lt;=20'b0; outlt;=20'b0; end  else if (result==1) begin  if (in_set==1'b0)  begin  in_1[3:0]lt;=a;  in_1[7:4]lt;=in_1[3:0];  in_1[11:8]lt;=in_1[7:4];  in_1[15:12]lt;=in_1[11:8];  in_1[19:16]lt;=in_1[15:12];  end     else if (in_set==1'b1)  begin  in_2[3:0]lt;=a;  in_2[7:4]lt;=in_2[3:0];  in_2[11:8]lt;=in_2[7:4];  in_2[15:12]lt;=in_2[11:8];  in_2[19:16]lt;=in_2[15:12];  end  end   else  begin  in_1lt;=in_1;  in_2lt;=in_2;  end  end   bcd2bin conver1(.bcd(in_1),.bin(cal1)); bcd2bin conver2(.bcd(in_2),.bin(cal2)); bcd2bin conver3(.bcd(in_2),.bin(cal2_1));  add_sub adsb  (.cal1(cal1),.calc2(cal2),.mode({selectmode,in_set}),.cal3(cal3)); mp multi(.cal1(cal1),.cal2(cal2),.cal3(cal3)); divider db(.cal1(cal1),.cal2_1(cal2_1),.cal3_1(cal3_1),.remain(remain));   bin2bcd_16 m1_1(.bin(cal3),.bcd_tt(m1[19:16]), .bcd_th(m1[15:12]),.bcd_h(m1[11:8]), .bcd_t(m1[7:4]),.bcd_o(m1[3:0]));  bin2bcd_16 m2_2(.bin(cal3),.bcd_tt(m1[19:16]), .bcd_th(m2[15:12]),.bcd_h(m2[11:8]), .bcd_t(m2[7:4]),.bcd_o(m2[3:0]));  bin2bcd_8   m3_3(.bin(cal3_1),.bcd_h(m3[11:8]),.bcd_t(m3[7:4]),.bcd_o(m3[3:0]));   always @ *  begin if (cal3 gt; 16'd32768)  ovlt;=1'b1; else   ovlt;=1'b0;  end  always @ (posedge clk, posedge result)  begin  if (result==1)  begin  case ({selectmode,in_set}) 3'b000 : outlt;=in_1; //first input 3'b001 : outlt;=in_2; //second input  3'b010 : outlt;=m1; //add 3'b011 : outlt;=m1; //sub 3'b100 : outlt;=m2; //multiple 3'b101 : outlt;=m3; //divide 3'b110 : outlt;=20'b0; //null 3'b111 : outlt;=20'b0; //null endcase end end    segdec b_0 (.i(out[3:0]),.o(digit0)); segdec b_1 (.i(out[7:4]),.o(digit1)); segdec b_2 (.i(out[11:8]),.o(digit2)); segdec b_3 (.i(out[15:12]),.o(digit3)); segdec b_4 (.i(out[19:16]),.o(digit4));  endmodule    module add_sub( input wire [15:0] cal1, input wire [15:0] cal2, input wire [2:0] mode, output reg [15:0] cal3 );  always @ *   begin  cal3lt;=16'b0;  if (mode==3'b010)  cal3lt;=cal1 cal2;  else if (mode==3'b011)  cal3lt;=cal1-cal2;  end  endmodule    module mp( input wire [15:0] cal1, input wire [15:0] cal2, output reg [15:0] cal3  );  reg [15:0] i;  always @ *  begin if (cal2==0) begin cal3lt;=0; end  else begin for (i=0;ilt;cal2;i=i 1) begin   cal3lt;=cal3 cal1; end   end end  endmodule     module divider( input wire [15:0] cal1, input wire [7:0] cal2_1, output reg [7:0] cal3_1, output reg [15:0] remain ); reg [15:0] i;  always @ *  begin  cal3_1lt;=8'b0; remainlt;=cal1;   for (i=0;ilt;2000;i=i 1) begin if (cal1gt;cal2_1)  begin  remainlt;=remain-cal2_1;  cal3_1=cal3_1 1'b1;  end else   begin cal3_1lt;=8'b0; remainlt;=cal1;   end end end endmodule     module SegDec( input wire [3:0]i, output reg [6:0]o );  always @ * case (i)  4'b0000 : o = 7'b1000000;//0  4'b0001 : o = 7'b1111001;//1  4'b0010 : o = 7'b0100100;//2  4'b0011 : o = 7'b0110000;//3  4'b0100 : o = 7'b0011001;//4  4'b0101 : o = 7'b0010010;//5  4'b0110 : o = 7'b0000010;//6  4'b0111 : o = 7'b1011000;//7  4'b1000 : o = 7'b0000000;//8  4'b1001 : o = 7'b0010000;//9 endcase  endmodule    module bcd2bin( input wire [19:0] bcd, output reg [15:0] bin  ); reg [3:0] i; reg [3:0] i1; reg [3:0] i2; reg [3:0] i3;  reg [15:0] io; reg [15:0] i1o; reg [15:0] i2o; reg [15:0] i3o;  always @ * begin io=0; i1o=0; i2o=0; i3o=0; if (bcd[3:0]lt;4'b1010) begin   if (bcd[19:4]==16'b0)  binlt;=bcd[3:0];   else if (bcd[19:8]==12'b0)  begin  for (i=0;ilt;bcd[7:4];i=i 1)  begin  io=io 16'd10;  end  binlt;=io bcd[3:0];  end    else if (bcd[19:12]==8'b0)  begin   for (i=0;ilt;bcd[7:4];i=i 1)  begin  io=io 4'd10;  end   for (i1=0;i1lt;bcd[11:8];i1=i1 1)  begin  i1o=i1o 16'd100;  end  binlt;=i1o io bcd[3:0];   end    else if (bcd[19:16]==4'b0)  begin  for (i=0;ilt;bcd[7:4];i=i 1)  begin  io=io 16'd10;  end   for (i1=0;i1lt;bcd[11:8];i1=i1 1)  begin  i1o=i1o 16'd100;  end   for (i2=0;i2lt;bcd[15:12];i2=i2 1)  begin   i2o=i2o 16'd1000;  end   binlt;=i2o i1o io bcd[3:0];  end   else   begin  for (i=0;ilt;bcd[7:4];i=i 1)  begin  io=io 16'd10;  end   for (i1=0;i1lt;bcd[11:8];i1=i1 1)  begin  i1o=i1o 16'd100;  end   for (i2=0;i2lt;bcd[15:12];i2=i2 1)  begin   i2o=i2o 16'd1000;  end   for (i3=0;i3lt;bcd[19:16];i3=i3 1)  begin  i3o=i3o 16'd10000;  end   binlt;=i3o i2o i1o io bcd[3:0];  end  end else bin={15{1'bx}}; end  endmodule    module bin2bcd_8( input wire [7:0] bin, output reg [3:0] bcd_h, output reg [3:0] bcd_t, output reg [3:0] bcd_o  );  reg [3:0] i;    always @ *  begin  {bcd_h,bcd_t,bcd_o} = 0;   for (i = 0; i lt; 8; i = i 1)   begin  {bcd_h,bcd_t,bcd_o} = {bcd_h[2:0],bcd_t,bcd_o ,bin[7-i]};   if(i lt; 7 amp;amp; bcd_o gt; 4)   bcd_o = bcd_o   3;  if(i lt; 7 amp;amp; bcd_t gt; 4)  bcd_t = bcd_t   3;  if(i lt; 7 amp;amp; bcd_h gt; 4)  bcd_h = bcd_h   3;   end  end    endmodule    module bin2bcd_16( input wire [19:0] bin, output reg [3:0] bcd_tt, output reg [3:0] bcd_th, output reg [3:0] bcd_h, output reg [3:0] bcd_t, output reg [3:0] bcd_o );  reg [5:0] i;    always @ *  begin  {bcd_tt,bcd_th,bcd_h,bcd_t,bcd_o} = 0;   for (i = 0; i lt; 16; i = i 1)   begin  {bcd_tt,bcd_th,bcd_h,bcd_t,bcd_o} =   {bcd_tt[2:0],bcd_th,bcd_h,bcd_t,bcd_o,bin[15-i]};   if(i lt; 7 amp;amp; bcd_o gt; 4)   bcd_o = bcd_o   3;  if(i lt; 7 amp;amp; bcd_t gt; 4)  bcd_t = bcd_t   3;  if(i lt; 7 amp;amp; bcd_h gt; 4)  bcd_h = bcd_h   3;   if(i lt; 7 amp;amp; bcd_th gt; 4)  bcd_th = bcd_th   3;   if(i lt; 7 amp;amp; bcd_tt gt; 4)  bcd_tt = bcd_tt   3;   end  end    endmodule  

а ниже приведен код испытательного стенда » шкала времени 1нс/1пс

 module calculator_tb;  reg [3:0] a; reg clk; reg rst; //sw9 reg result; //key0 reg in_set; //sw4 reg [1:0] selectmode; //sw6-5 reg mode; //sw7 1(-) 0( ) wire ov; //ledr9 reg [19:0] in_1; //first_input reg [19:0] in_2; //second_input  wire [19:0] out; //final output wire [15:0] remain; //divide calculation remain wire [19:0] m1; //add_sub result wire [19:0] m2; //multiple result wire [11:0] m3; //division result wire [6:0] digit4; wire [6:0] digit3; wire [6:0] digit2; wire [6:0] digit1;  wire [6:0] digit0;   calculator_p utt( .a(a), .clk(clk), .rst(rst), .result(result), .in_set(in_set), .selectmode(selectmode), .mode(mode), .ov(ov), .in_1(in_1), .in_2(in_2), .out(out), .remain(remain), .m1(m1), .m2(m2), .m3(m3), .digit4(digit4), .digit3(digit3), .digit2(digit2), .digit1(digit1), .digit0(digit0) );  initial begin  clklt;=1'b0; #1 clk=~clk;  end  initial begin rstlt;=1'b0; #5 rst=~rst; end  initial begin {selectmode,in_set}lt;=3'b000; #30 {selectmode,in_set}lt;=3'b001; #60 {selectmode,in_set}lt;=3'b010; #100 {selectmode,in_set}lt;=3'b011; end  initial begin resultlt;=1'b1; #27 resultlt;=1'b0; #29 resultlt;=1'b1; #56 result=1'b0; #105 result=1'b1; end   initial begin alt;=4'b0; #15 alt;=4'b0010; #21 alt;=4'b0001; #34 alt;=4'b0111; end   endmodule  

у компиляции нет проблем…и у другого тестового стенда тоже нет проблем…в течение 2 недель я ничего не могу сделать, пожалуйста, помогите мне, умные ребята……

Ответ №1:

Я не полностью отладил ваш код, но вот некоторые проблемы, которые я заметил:

В calculator_p списке удалить negedge result и posedge result из списков чувствительности. Наличие их в списке чувствительности и ссылка на них в блоке сообщают синтезатору, что они являются асинхронными сигналами.

Возможно, вам также потребуется удалить его rst из списка чувствительности. FGPA обычно имеют ограниченную поддержку асинхронного сброса. Вы можете поддерживать его, а можете и не поддерживать, или может быть только несколько триггеров с асинхронным сбросом. Удаление его из списка чувствительности.

mp Модуль неправильно используется при неблокирующем назначении, и цикл for не может статически развернуться. Предполагаемый эквивалентный код был бы таким, как показано ниже (64-килобайтные циклы большие и медленные; возможно, потребуется переосмысление). Аналогичная проблема существует и в bcd2bin .

 always @* begin  cal3 = 0;  for (i=1;ilt;(2lt;lt;16);i=i 1) begin  if (ilt;cal2) begin  cal3 = cal3 cal1;  end  end end  

В общем случае комбинационные блоки должны использовать блокирующие назначения, синхронные блоки должны использовать неблокирующие назначения.