我是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
我认为这是一个简单的代码而且没有时间,但现在我无法合成我的代码?问题出在哪儿?请帮助我!!! 感谢
答案 0 :(得分:2)
问题在于你如何访问ram数组。你是在一个组合块里面做的。这使得XST使用分布式RAM(而不是Block RAM)构建RAM,并构建大量多路复用器,以涵盖ADDRA/ADDRB/ADDRC/ADDRD
信号的所有1024种可能组合。这就是你经历长时间合成的原因。
重新考虑您的逻辑,以便ram[ADDR] <= value
或value <= ram[ADDR]
等代码始终位于始终触发的时钟内
编辑完代码后:我建议将quadport 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将其推断为Block 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实例化为您的quadport设计并根据您的状态复用信号。像这样:
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
答案 1 :(得分:0)
您可能应该在时钟边缘触发ram读写操作,而不是在电平敏感信号上触发。
你的合成器可能无法理解state
是一个伪时钟,并试图推断一些奇怪的非ram行为,这可能会产生一个难以合成的巨大逻辑锥。