我有一个应用程序,其中我以慢时钟速度(clk_a)连续写入块ram,并且在这个慢时钟周期内,需要以快时钟速度(clk_b)从块ram读取三个索引,以将这些值用作数学模块中的操作数,结果将在下一个慢时钟回写到块ram。这三个索引是在慢时钟后沿写入的当前地址,加上两个紧邻的地址(addr_a -1和addr_a +1)。
合成它的有效方法是什么?到目前为止,我最好的尝试是使用一个小计数器(三元组),它以快速时钟频率运行,递增地址,但我最终耗尽了逻辑,因为看起来Yosys没有正确推断ram。对此有什么好的策略?
这就是我所拥有的:
module myRam2 (
input clk_a,
input clk_b,
input we_a,
input re_a,
input [10:0] addr_a,
input [10:0] addr_b,
input [11:0] din_a,
output [11:0] leftNeighbor,
output [11:0] currentX,
output [11:0] rightNeighbor
);
parameter MEM_INIT_FILE2 = "";
initial
if (MEM_INIT_FILE2 != "")
$readmemh(MEM_INIT_FILE2, ram2);
reg [11:0] ram2 [0:2047];
reg [1:0] triplet = 3;
reg [10:0] old_addr_a;
reg [11:0] temp;
always @(posedge clk_a) begin
ram2[addr_a] <= din_a;
end
always@(posedge clk_b)
if (old_addr_a != addr_a) begin
triplet <= 0;
old_addr_a <= addr_a;
end
else
if(triplet < 3) begin
triplet <= triplet +1;
end
always @(posedge clk_b) begin
temp <= ram2[addr_a + (triplet - 1)];
end
always @(posedge clk_b) begin
case(triplet)
0: leftN <= temp;
1: X <= temp;
2: rightN <= temp;
endcase
end
reg signed [11:0] leftN;
reg signed [11:0] X;
reg signed [11:0] rightN;
assign leftNeighbor = leftN;
assign currentX = X;
assign rightNeighbor = rightN;
endmodule
发布于 2020-07-19 06:18:12
关于效率,以下方法应该有效,并且不需要更快的时钟:
module myRam2 (
input wire clk,
input wire we,
input wire re,
input wire [10:0] addr_a,
input wire [10:0] addr_b,
input wire [11:0] din_a,
output reg [11:0] leftNeighbor,
output reg [11:0] currentX,
output reg [11:0] rightNeighbor
);
reg [11:0] ram2 [2047:0];/* synthesis syn_ramstyle = "no_rw_check" */;
always @(posedge clk) begin
if(we) ram2[addr_a] <= din_a;
if(re) {leftNeighbor,currentX,rightNeighbor} <= {ram2[addr_b-1],ram2[addr_b],ram2[addr_b+1]};
end
endmodule
综合关键字在过去帮助我增加了正确推断ram的可能性。
编辑:删除了建议一维映射的第二个示例。事实证明,至少Lattice LSE不能处理这种方法。然而,第一个被截取的代码应该可以根据Active-HDL和Lattice工作。
https://stackoverflow.com/questions/62950456
复制相似问题