Hi. In my design I am writing to a dual port block ram at a slow clock speed and need, within that slow clock cycle (clk_a), to read the immediate neighbors (addr a -1 and addra + 1) at a fast clock (clk_b) to use them as operands in a math module. I am having trouble getting yosys to fit the logic/memory needed into my BlackIce Mx for it to work. In my most successful attempt, using a slightly modified version of @lawrie's dual port ram, I use a clock to drive sequential read operations when the write address is updated. But I cannot get it to fit: my design is getting a bit big, but without this module I'm still around 68% resource use for both logic and memory.
Do you masters know of a more efficient way to read these values within one clock cycle of the write clock?
Below is what I currently have. I also have another ram storing similar data for my lcd, as well as another one that is buffering a dac. All three modules basically hold the same data but read them off at different rates... current set up with this module added give me 87% of ram use but 107% of logic use.
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