【问题标题】:synthesize-xst in xillinx get a long timexilinx 中的 synthesize-xst 得到了很长时间
【发布时间】:2013-12-31 07:46:57
【问题描述】:

我是verilog和xilinx的初学者,我正在用verilog编写一个四端口ram,

我想合成我的代码,但是我的代码虽然很小,但是合成需要很长时间,我强行停止它,我无法合成我的代码。

我不知道问题出在哪里,我该怎么办?这是我自己的代码..

module Dram(CLKM,WEA,WEB,WEC,WED,ENA,ENB,ENC,END,DIA,DIB,DIC,DID,ADDRA,ADDRB,ADDRC,ADDRD,DOA,DOB,DOC,DOD);
input WEA,WEB,WEC,WED,ENA,ENB,ENC,END;
input [17:0]DIA,DIB,DIC,DID;
input [9:0]ADDRA,ADDRB,ADDRC,ADDRD;
input CLKM;
output reg [17:0] DOA,DOB,DOC,DOD;
reg state_reg,state_next;
reg [17:0]ram[1023:0];
always@(posedge CLKM)
begin
    state_reg=state_next;
end///edn for always
always@(negedge  CLKM)
begin
    case(state_reg)
        1'b0:
        begin
            if(ENA)
            begin
                if(WEA)
                    ram[ADDRA]<=DIA;
                DOA<=ram[ADDRA];
            end//////for enA
            if(ENB)
            begin
                if(WEB)
                    ram[ADDRB]<=DIB;
                DOB<=ram[ADDRB];
            end////for enB
            state_next=1'b1;
        end////for 1'b0
        1'b1:
        begin
            if(ENC)
            begin
                if(WEC)
                    ram[ADDRC]<=DIC;
                DOC<=ram[ADDRC];
            end
            if(END)
            begin
                if(WED==1'b1)
                    ram[ADDRD]<=DID;
                DOD<=ram[ADDRD];
            end
            state_next=1'b0;
        end///end for 1'b1
    endcase
end//end for always

endmodule

我认为这是一个简单的代码,并没有得到很多时间,但现在我无法合成我的代码?哪里有问题?请帮帮我!!! 谢谢

【问题讨论】:

  • 很好的做法是很好地格式化您的代码以使其更易于阅读。使用 sp.ace 进行缩进而不是制表符。

标签: verilog xilinx synthesis


【解决方案1】:

问题在于如何访问 ram 数组。您正在组合块内执行此操作。这使得 XST 可以使用分布式 RAM 而不是块 RAM 构建您的 RAM,并构建大量多路复用器来覆盖 ADDRA/ADDRB/ADDRC/ADDRD 信号的所有 1024 种可能组合。这就是为什么你会经历很长的合成时间。

重新思考你的逻辑,让ram[ADDR] &lt;= valuevalue &lt;= ram[ADDR] 之类的代码始终在始终触发的时钟内


在您编辑代码之后:然后我建议将四端口 RAM 逻辑与 RAM 逻辑本身分开。你在一个标准的单端口 RAM 模块上进行中继,然后使用 FSM,让它表现得好像它有很多端口,不是吗?您的单端口 RAM,以及您头疼的原因可以这样描述:

module spram (input wire clk,
  input wire en,
  input wire we,
  input wire [9:0] addr,
  input wire [17:0] din,
  output reg [17:0] dout
  );

  reg [17:0] ram[0:1023];

  always @(negedge clk) begin
    if (en) begin
      if (we) begin
        ram[addr] <= din;
      end
      dout <= ram[addr];
    end
  end
endmodule

以这种方式描述内存将有助于 XST 将其推断为块 RAM 设备,正如高级综合报告所指出的那样:

Synthesizing (advanced) Unit <spram>.
INFO:Xst:3040 - The RAM <Mram_ram> will be implemented as a BLOCK RAM, absorbing the following register(s): <dout>
    -----------------------------------------------------------------------
    | ram_type           | Block                               |          |
    -----------------------------------------------------------------------
    | Port A                                                              |
    |     aspect ratio   | 1024-word x 18-bit                  |          |
    |     mode           | read-first                          |          |
    |     clkA           | connected to signal <clk>           | fall     |
    |     enA            | connected to signal <en>            | high     |
    |     weA            | connected to signal <we>            | high     |
    |     addrA          | connected to signal <addr>          |          |
    |     diA            | connected to signal <din>           |          |
    |     doA            | connected to signal <dout>          |          |
    -----------------------------------------------------------------------
    | optimization       | speed                               |          |
    -----------------------------------------------------------------------
Unit <spram> synthesized (advanced).

然后,您可以将此 RAM 实例化到您的四端口设计中,并根据您所处的状态多路复用信号。像这样的:

module qpram (input wire clk,
  input wire [3:0] en,
  input wire [3:0] we,
  input wire [9:0] addra,
  input wire [9:0] addrb,
  input wire [9:0] addrc,
  input wire [9:0] addrd,
  input wire [17:0] dina,
  input wire [17:0] dinb,
  input wire [17:0] dinc,
  input wire [17:0] dind,
  output reg [17:0] douta,
  output reg [17:0] doutb,
  output reg [17:0] doutc,
  output reg [17:0] doutd
  );

  reg [1:0] port = 2'b00; /* indicates which port is active */
  always @(negedge clk) begin
    port <= port + 1;
  end

  /* instantiate single port RAM */
  reg enable,write;
  reg [17:0] din;
  wire [17:0] dout;
  reg [9:0] addr;
  spram myram (clk,enable,write,addr,din,dout);

  /* multiplexers to assign right inputs to RAM
  depending on which port we are in */
  always @* begin
    case (port)
      2'b00 : begin
                addr = addra;
                write = we[0];
                enable = en[0];
                din = dina;
              end
      2'b01 : begin
                addr = addrb;
                write = we[1];
                enable = en[1];
                din = dinb;
              end
      2'b10 : begin
                addr = addrc;
                write = we[2];
                enable = en[2];
                din = dinc;
              end
      2'b11 : begin
                addr = addrd;
                write = we[3];
                enable = en[3];
                din = dinc;
              end
    endcase
  end

  /* data out is available at the end of each clock cycle */
  always @(negedge clk) begin
    case (port)
      2'b00 : douta <= dout;
      2'b01 : doutb <= dout;
      2'b10 : doutc <= dout;
      2'b11 : doutd <= dout;
    endcase
  end
endmodule

【讨论】:

  • 现在,我已经编辑了我的代码,您可以在上面查看它,并使用时钟中的 ram 始终如您所说的那样触发,但是高级 hdl 合成也需要很长时间!!我该怎么办?
【解决方案2】:

您可能应该在时钟边缘触发 RAM 读取和写入,而不是在电平敏感信号上。

您的合成器可能无法理解 state 是一个伪时钟,并试图推断出一些奇怪的非 RAM 行为,这可能会生成一个难以合成的巨大逻辑锥。

【讨论】:

  • 谢谢@Tim,是的,我认为“状态”是问题所在,但我应该怎么做,我需要它,这是我的设计所必需的,我只是想在我的设计,我是按州来做的。
  • 您仍然可以在时钟块内使用if(state)。只需将always@(state) 替换为always@(negedge CLKM),我认为它应该会有所帮助。
  • 我做到了,现在我的一段代码是这样的,但也需要时间,我认为状态又是问题!输出注册状态;注册 [17:0] 内存 [1023:0];总是@(negedge CLKM) 开始 if(state==1'b0) state
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多