【问题标题】:Vivado 2016.1: Upon synthesis it is removing useful logic. VerilogVivado 2016.1:在综合时,它正在删除有用的逻辑。 Verilog
【发布时间】:2016-11-03 04:53:16
【问题描述】:

我目前正在构建一个软核处理器,但在合成 Verilog 实现的 RAM 和其他顺序元素时遇到了麻烦。我决定单独处理处理器的每个部分,以了解发生了什么,恐怕还没有运气。我试图合成的电路主要做两件事:用时钟驱动的数据填充内存;内存充满数据后,一个标志将指示向外部处理器发送信号,外部处理器将发送另一个称为就绪的信号,以便读取和存储内存内容。

这些是模块:

顶部模块

module DATATEST(clk,JRED,led,jd,ja);
 
 input clk;
 input  JRED;
 output [1:0] led;
 output [7:0] ja;
 output [1:0] jd;
 
 
 
 wire RESP,FLAG,RDY,SENT,CL;
 wire [7:0] DATA;
 
 wire BFLAG, BCL,BFL,BL;
 wire WD;
 wire [31:0] MR,MW,FAD,LAD,AD;
 
 assign CL = clk;
 assign RDY = JRED;
 assign led[0] = BL;
 assign led[1] = SENT;
 assign ja = DATA;
 assign jd[0] = RESP; 
 assign jd[1] = FLAG;
 
  fill_mem FM1(.clock(BCL),.flag(FLAG),.out(MW),.ad(FAD));

  not_gate NG1(.I(BFLAG),.O(WD));

  mux MUX1(.a(FAD),.b(LAD),.c(BFL),.o(AD));

  data_memory DM1(.address(AD),.wr_da(MW),.mem_write(WD),.mem_read(FLAG),.re_da(MR));

  com_out CM1(.ready(RDY),.flag(BFL),.in(MR),.out(DATA),.sent(SENT),.response(RESP),
  .address(LAD));
 

  buffer F1(.in(FLAG),.out(BFLAG));

  buffer F2(.in(FLAG),.out(BFL));

  buffer F3(.in(FLAG),.out(BL));

  buffer C1(.in(CL),.out(BCL));
  
endmodule
`

其他模块:

module data_memory(address,wr_da,mem_write,mem_read,re_da);
 
 parameter SIZE = 16;
 input [31:0] address;
 input [31:0] wr_da;
 input mem_write;
 input mem_read;
 output [31:0] re_da;
  
 reg [7:0] MEM [0:SIZE-1];
 
 assign re_da = (mem_read == 1) ? {MEM[address],MEM[address+1],MEM[address+2],MEM[address+3]}:0 ;
 
 always @ (wr_da, address)
  begin
 
  
 
    if (mem_write == 1)
    begin
     MEM[address] = wr_da[31:24];
     MEM[address+1] = wr_da[23:16];
     MEM[address+2] = wr_da[15:8];
     MEM[address+3] = wr_da[7:0];
    end

   
  
  end

module mux(a,b,c,o);

 parameter N = 32;
 input [N-1:0] a;
 input [N-1:0] b;
 input c;
 output reg [N-1:0] o = 0;

 always @*
 begin
 
  o = 0;
 
  case (c)
   
   0: o = a;
   1: o = b;
  
   default: o = 0;
  
  endcase

 end
 
endmodule

module com_out(ready,flag,in,out,sent,response,address);

 input ready;
 input flag;
 input [31:0] in;
 output reg [7:0] out;
 output reg sent;
 output reg [31:0] address = 0;
 output  response;
 reg SINT = 0;
 reg COUNT = 0;
 reg R = 0; 
 reg [15:0] SEND = 0;
 wire  [7:0] DATA [3:0];
 
 assign DATA[0] = in[31:24];
 assign DATA[1] = in[23:16];
 assign DATA[2] = in[15:8];
 assign DATA[3] = in[7:0];
 
 assign response = (R == 1) ? 1:0;
  
 always @ (ready)
 begin
  out = 0;
  
  if (ready == 1)
  begin
  
   if ((flag==1) && (SINT==0))
    begin
   
     out = DATA[SEND];
     R = 1;
     SEND = SEND+1;
   
     if (SEND==4)
     begin
      address = address + 4;
      SEND = 0; 
      COUNT = COUNT + 1; 
     end
     else
      address = address;
      
    end
   
    else
     out = 0;
   
   end
   
   else 
    R = 0;

   
   if (COUNT == 4)
   begin
    sent = 1;
    SINT = 1;
   end
   
   else
   begin
    sent = 0;
    SINT = 0;
   end
 end
 
endmodule


module fill_mem (clock,flag,out,ad);
 
 input clock;
 output reg flag = 0;
 output reg [31:0] out = 0; 
 output  [31:0] ad ;
 reg [31:0] COMP = 0;
 reg [31:0] COND = 0;
 assign ad = COND;
 
 always @ (negedge clock)
 begin
  
  COMP = COMP + 4;
  COND = COMP - 4;
  
  case  (COND)
   0 : out = 32'hACDECACA; 
   4 : out =  32'hACAFECAD; 
   8: out = 32'hCAFEBEEF; 
   12: out = 32'hDEADCAFE; 
   default: out = 0; 
  endcase
  
  
  
  if (COMP >= 20)
   flag = 1;
  else
   flag = 0;
   
 end
endmodule

即使模拟完美运行,合成也会引发一些警告消息:

警告信息

[Synth 8-3332] Sequential element (FM1/out_reg[31]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[27]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[26]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[25]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[24]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[23]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[20]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[19]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[18]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[11]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[10]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[9]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[7]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[5]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[4]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[3]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[2]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[1]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[0]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/COND_reg[0]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[0][3]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[1][3]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[2][3]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[3][3]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[4][3]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[5][3]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[6][3]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[7][3]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[8][3]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[9][3]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[10][3]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[11][3]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[12][3]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[13][3]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[14][3]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[15][3]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/COMP_reg[0]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/COMP_reg[1]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/COND_reg[1]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (FM1/out_reg[8]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[0][0]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[2][0]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[4][0]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[6][0]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[8][0]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[10][0]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[12][0]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (DM1/MEM_reg[14][0]) is unused and will be removed from module DATATEST.

[Synth 8-3332] Sequential element (CM1/address_reg[0]) is unused and will be removed from module DATATEST.

我希望我能理解原因,因为所有元素都被实际使用了。

所以,如果能帮助我找出问题所在以及如何解决它,我将不胜感激。在此先感谢:D T.T

【问题讨论】:

  • 您知道综合会创建硬件,因此如果您用一些常量数据填充内存,而不是从中读取,综合工具将对其进行优化。我真的不明白你在做什么,这不是 HDL,这是 SW 顺序思维。
  • 问题是我确实读取了这些数据。 com__out 模块在内存填满后提取此信息,这是用于 FPGA 功能测试。是的,它是顺序的,因为它与时钟信号同步。这是针对处理器的,处理器按顺序工作(除非您使用流水线,我没有使用它,但它们仍然按顺序读取指令)。所以是的,我需要先填充它。他们读取它的内容,因为不应该同时读取和写入内存。
  • 内存在 4 个时钟周期内被填满。一旦 fill_mem 模块完成了这个任务,它就会产生一个标志(实际上是一个输出),并将这个信号发送到一些 muxes 和 com_out。现在 com_out 能够提取由信号就绪(FPGA 输入)控制的信息。我打算用微控制器提取这些信息来做一些其他的事情,这就是为什么我也需要它是连续的。
  • 但是再一次,如果你认为我做错了,请告诉我应该怎么做。这就是我来这里寻求帮助的原因 n.n
  • 仅供参考,您在 com_out 中有组合循环。此外always @ (ready) 会在模拟和合成电路之间造成功能不匹配。必须指定完整的敏感度列表以避免不匹配,或使用always @*。应为锁存器和触发器分配非阻塞 (<=) 分配,而不是阻塞 (=) 分配。

标签: verilog fpga ram synthesis vivado


【解决方案1】:

代码现在完美运行。我在一些东西上使用了 don_touch,修改了 RAM 上的一些代码,并决定制作不同的输出和 TOP 模块,以实现更简单的 FPGA 测试方法。基本上,fill_mem 模块用数据填充内存(顾名思义),然后内存被另一个模块读取,该模块被带到板上的一些 LED 上,可以检查存储的字节。使用开关选择读取地址。

顶部模块

module RAM_LEDS( clk, sw, led,lr,lb);

 input clk;
 input [3:0] sw;
 output [3:0] led;
 output [3:0] lr;
 output [0:0] lb;




     wire FLAG;


     wire [3:0] EXT;

     wire WD;
     wire [31:0] MR,MW;
     wire [4:0] RESU, A/*,B*/,FAD,LAD,AD,TA;
     wire [7:0] LO;

     assign led = LO[3:0];
     assign lr =  LO[7:4];  
     assign lb[0] = FLAG;
     assign EXT = sw;


    fill_mem FM1(.a(A),.out(MW),.ad(FAD));

    adder_oi #(5) A1(.p(A),.result(RESU));

    not_gate NG1(.I(FLAG),.O(WD));


    mux #(5) MUX1(.a(FAD),.b(LAD),.c(FLAG),.o(AD));

    bus #(5) B1(.clk(clk),.I(RESU),.O(A));

    data_memory DM1(.clock(clk),.address(AD),.wr_da(MW),.mem_write(WD),.mem_read(FLAG),.re_da(MR));

    peripheral P1(.a(FAD),.flag(FLAG));

    extend EX1(.I(EXT),.O(TA));

    switching S1(.ai(TA),.data(MR),.leds(LO),.ao(LAD));

endmodule

实例化模块

用于从 RAM 读取的硬件

module peripheral(a,flag);
parameter A = 5;
input [A-1:0] a;
output flag;

assign flag = (a == 20) ? 1:0;
assign flag = (a == 20) ? 1:0;

endmodule

module extend(I,O);

 input [3:0] I;
 output [4:0] O;

 assign O = {1'b0,I};

endmodule

module switching(ai,data,leds,ao);

input [4:0] ai;
input [31:0] data;
output reg [7:0] leds;
output reg [4:0] ao;

wire [7:0] D [0:3];
assign D[0] = data[7:0];
assign D[1] = data[15:8];
assign D[2] = data[23:16];
assign D[3] = data[31:24];

always @*
begin

case (ai)
0,1,2,3: ao = 0;
4,5,6,7: ao = 4;
8,9,10,11: ao = 8;
12,13,14,15: ao = 12;
default: ao = 0;
endcase

leds = D[ai%4];


end
endmodule

用于填充 RAM 的硬件

module fill_mem (a,out,ad);
 parameter A = 5;
 input [A-1:0] a;
 output [31:0] out; 
 output  [A-1:0] ad;
 (* dont_touch = "true" *) reg [31:0] O = 0;
 (* dont_touch = "true" *) reg [A-1:0] AR = 0;
 assign out = O;
 assign ad = AR;

 always @*
 begin


  case  (a)
   0: begin AR = 0; O = 32'h00000000;; end
   4: begin AR = 4; O = 32'hFFF00F00;  end
   8:  begin AR =  8; O = 32'h9669C33C; end
   12: begin AR = 12; O = 32'hF173371F;  end
   16: begin AR = 16; O = 32'hFFFFFFFF; end
   default: begin AR = 20; O = 0;  end 
  endcase

 end
endmodule

module bus(clk,I,O);
parameter N = 32;
input clk;
input [N-1:0] I;
output [N-1:0] O;
(* dont_touch = "true" *)reg [N-1:0] C = 0;
assign O = C;

always @(posedge clk)
begin

C = I;

end
endmodule

module adder_oi(p,result); //PC+4

 parameter N =32;
 input [N-1:0] p;
 output [N-1:0] result;

 assign result = p + 4;

endmodule

杂项。

module mux(a,b,c,o);

 parameter N = 32;
 input [N-1:0] a;
 input [N-1:0] b;
 input c;
 output reg [N-1:0] o = 0;

 always @*
 begin

  o = 0;

  case (c)

   0: o = a;
   1: o = b;

   default: o = 0;

  endcase

 end

endmodule

DA RAM 本身

module data_memory(clock,address,wr_da,mem_write,mem_read,re_da);

 parameter SIZE = 24;
 parameter A = 5;
 input [A-1:0] address;
 input clock;
 input [31:0] wr_da;
 input mem_write;
 input mem_read;

 output  [31:0] re_da;

 (* ram_style = "auto" *) reg [31:0] MEM [0:SIZE-1];

 assign re_da = (mem_read) ? MEM[address]:0;

 always @(negedge clock)
  begin



    if  ((mem_write) &&(!mem_read))
    begin
     MEM[address] <= wr_da;

    end


  end


 endmodule

就是这样。现在剩下的唯一想法就是测试完整的处理器。

【讨论】:

    【解决方案2】:

    为了防止合成器删除“未使用”的逻辑,我在声明要保留的变量之前使用了此语句:

    EXAMPLE: 
    (*dont_touch = "true"*) output reg [7:0] out;
    (*dont_touch = "true"*) reg COUNT = 0;
    ......
    

    感谢那些不厌其烦地尝试详细说明我不太了解的事情的人。

    【讨论】:

    • 这相当于忽略编译警告并覆盖它说“我知道我在做什么”。
    • 我知道。一旦我在 FPGA 中测试代码,我就会知道我是否正确。总比去掉逻辑要好,那样电路也不行。
    • 还有,为什么只批评?我的意思是,你可以帮助并告诉我应该怎么做而不是@dave。对我来说,如果你不纠正他们,说别人错了是没有意义的 xD 我一直在自己学习所有这些,没有人帮助我,现在,我试着寻求帮助,这就是这样 XD Welp,生活有时很讽刺。有一个美好的一天戴夫。
    • 我不确定答案,但我知道不是这样。如果您有一个较小的示例来显示此行为,那么我可能会更好地展示如何解决它。我的评论不是给你的,而是给下一个看到相同错误消息并想知道如何解决它的人,然后我想让他们知道这不是正确的答案。
    • 嗯,我明白你的意思,我是这样做的。 FPGA 测试成功 n.n 我对代码做了一些修改,因为合成器没有正确推断 RAM。但不要触摸其余的工作正常。也许这不是每个项目的正确答案,但它解决了我的部分问题:) 所以,保持开放的心态,我也会这样做,因为你的话也有一定的道理。@dave
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多