📄 altmemddr_mem_model.v
字号:
begin
if (reset_n == 0)
begin
write_cmd_echo <= 0;
read_cmd_echo <= 0;
end
else // No Activity if the clock is
if (cke)
begin
// This is a read command
if (cmd_code == 3'b101)
read_cmd <= 1'b1;
else
read_cmd <= 1'b0;
// This is a write command
if (cmd_code == 3'b100)
write_cmd <= 1'b1;
else
write_cmd <= 1'b0;
// This is an activate - store the chip/row/bank address in the same order as the DDR controller
if (cmd_code == 3'b011)
open_rows[current_row] <= a;
end
end
// Pipes are flushed here
always @(posedge clk or negedge reset_n)
begin
if (reset_n == 0)
begin
wr_addr_pipe_1 <= 0;
wr_addr_pipe_2 <= 0;
wr_addr_pipe_3 <= 0;
wr_addr_pipe_4 <= 0;
wr_addr_pipe_5 <= 0;
wr_addr_pipe_6 <= 0;
wr_addr_pipe_7 <= 0;
wr_addr_pipe_8 <= 0;
wr_addr_pipe_9 <= 0;
wr_addr_pipe_10 <= 0;
rd_addr_pipe_1 <= 0;
rd_addr_pipe_2 <= 0;
rd_addr_pipe_3 <= 0;
rd_addr_pipe_4 <= 0;
rd_addr_pipe_5 <= 0;
rd_addr_pipe_6 <= 0;
rd_addr_pipe_7 <= 0;
rd_addr_pipe_8 <= 0;
rd_addr_pipe_9 <= 0;
rd_addr_pipe_10 <= 0;
end
else // No Activity if the clock is
if (cke)
begin
rd_addr_pipe_10 <= rd_addr_pipe_9;
rd_addr_pipe_9 <= rd_addr_pipe_8;
rd_addr_pipe_8 <= rd_addr_pipe_7;
rd_addr_pipe_7 <= rd_addr_pipe_6;
rd_addr_pipe_6 <= rd_addr_pipe_5;
rd_addr_pipe_5 <= rd_addr_pipe_4;
rd_addr_pipe_4 <= rd_addr_pipe_3;
rd_addr_pipe_3 <= rd_addr_pipe_2;
rd_addr_pipe_2 <= rd_addr_pipe_1;
rd_addr_pipe_1 <= rd_addr_pipe_0;
rd_valid_pipe[10 : 1] <= rd_valid_pipe[9 : 0];
rd_valid_pipe[0] <= cmd_code == 3'b101;
wr_addr_pipe_10 <= wr_addr_pipe_9;
wr_addr_pipe_9 <= wr_addr_pipe_8;
wr_addr_pipe_8 <= wr_addr_pipe_7;
wr_addr_pipe_7 <= wr_addr_pipe_6;
wr_addr_pipe_6 <= wr_addr_pipe_5;
wr_addr_pipe_5 <= wr_addr_pipe_4;
wr_addr_pipe_4 <= wr_addr_pipe_3;
wr_addr_pipe_3 <= wr_addr_pipe_2;
wr_addr_pipe_2 <= wr_addr_pipe_1;
wr_addr_pipe_1 <= wr_addr_pipe_0;
wr_valid_pipe[10 : 1] <= wr_valid_pipe[9 : 0];
wr_valid_pipe[0] <= cmd_code == 3'b100;
wr_addr_delayed_r <= wr_addr_delayed;
end
end
// Decode CAS Latency from bits a[6:4]
always @(posedge clk)
begin
// No Activity if the clock is
if (cke)
//Load mode register - set CAS latency, burst mode and length
if (cmd_code == 3'b000 && ba == 2'b00)
begin
burstmode <= a[3];
burstlength <= a[2 : 0] << 1;
//CAS Latency = 2.0
if (a[6 : 4] == 3'b010)
index <= 4'b0001;
else //CAS Latency = 2.5
if (a[6 : 4] == 3'b110)
index <= 4'b0001;
else //CAS Latency = 3.0
if (a[6 : 4] == 3'b011)
index <= 4'b0010;
else //CAS Latency = 4.0
if (a[6 : 4] == 3'b100)
index <= 4'b0011;
else
index <= 4'b0100;
end
end
always @(posedge clk)
begin
// Reset write address otherwise if the first write is partial it breaks!
if (cmd_code == 3'b000 && ba == 2'b00)
wr_addr_pipe_0 <= 0;
else if (cmd_code == 3'b100)
wr_addr_pipe_0 <= {ba,open_rows[current_row],addr_col};
//Read request so store the read address
if (cmd_code == 3'b101)
rd_addr_pipe_0 <= {ba,open_rows[current_row],addr_col};
end
// read data transition from single to double clock rate
always @(posedge clk)
begin
first_half_dq <= read_data[31 : 16];
second_half_dq <= read_data[15 : 0];
end
assign read_dq = clk ? second_half_dq : first_half_dq;
assign dq_temp = dq_valid ? read_dq : {16{1'bz}};
assign dqs_temp = dqs_valid ? {2{clk}} : {2{1'bz}};
assign mem_dqs = dqs_temp;
assign mem_dq = dq_temp;
//Pipelining registers for burst counting
always @(posedge clk)
begin
write_valid_r <= write_valid;
read_valid_r <= read_valid;
write_valid_r2 <= write_valid_r;
write_valid_r3 <= write_valid_r2;
write_to_ram_r <= write_to_ram;
read_valid_r2 <= read_valid_r;
read_valid_r3 <= read_valid_r2;
read_valid_r4 <= read_valid_r3;
end
assign write_to_ram = write_valid;
assign dq_valid = read_valid_r;
assign dqs_valid = dq_valid || dqs_valid_temp;
//
always @(negedge clk)
begin
dqs_valid_temp <= read_valid;
end
//capture first half of write data with rising edge of DQS, for simulation use only 1 DQS pin
always @(posedge mem_dqs[0])
begin
#0.1 dq_captured[15 : 0] <= mem_dq[15 : 0];
#0.1 dm_captured[1 : 0] <= mem_dm[1 : 0];
end
//capture second half of write data with falling edge of DQS, for simulation use only 1 DQS pin
always @(negedge mem_dqs[0])
begin
#0.1 dq_captured[31 : 16] <= mem_dq[15 : 0];
#0.1 dm_captured[3 : 2] <= mem_dm[1 : 0];
end
//Support for incomplete writes, do a read-modify-write with mem_bytes and the write data
always @(posedge clk)
begin
if (write_to_ram)
rmw_temp[7 : 0] <= dm_captured[0] ? mem_bytes[7 : 0] : dq_captured[7 : 0];
end
always @(posedge clk)
begin
if (write_to_ram)
rmw_temp[15 : 8] <= dm_captured[1] ? mem_bytes[15 : 8] : dq_captured[15 : 8];
end
always @(posedge clk)
begin
if (write_to_ram)
rmw_temp[23 : 16] <= dm_captured[2] ? mem_bytes[23 : 16] : dq_captured[23 : 16];
end
always @(posedge clk)
begin
if (write_to_ram)
rmw_temp[31 : 24] <= dm_captured[3] ? mem_bytes[31 : 24] : dq_captured[31 : 24];
end
assign wr_addr_delayed = wr_addr_pipe_1;
//Pipelining registers for burst counting
always @(posedge clk)
begin
write_valid <= write_cmd;
end
assign mem_bytes = (rmw_address == wr_addr_delayed_r) ? rmw_temp : read_data;
assign rmw_address = (write_to_ram) ? wr_addr_delayed : read_addr_delayed;
//use index to select which pipeline stage drives addr
assign read_addr_delayed = (index == 0)? rd_addr_pipe_0 :
(index == 1)? rd_addr_pipe_1 :
(index == 2)? rd_addr_pipe_2 :
(index == 3)? rd_addr_pipe_3 :
(index == 4)? rd_addr_pipe_4 :
(index == 5)? rd_addr_pipe_5 :
(index == 6)? rd_addr_pipe_6 :
(index == 7)? rd_addr_pipe_7 :
(index == 8)? rd_addr_pipe_8 :
(index == 9)? rd_addr_pipe_9 :
rd_addr_pipe_10;
//use index to select which pipeline stage drives valid
assign read_valid = (index == 0)? rd_valid_pipe[0] :
(index == 1)? rd_valid_pipe[1] :
(index == 2)? rd_valid_pipe[2] :
(index == 3)? rd_valid_pipe[3] :
(index == 4)? rd_valid_pipe[4] :
(index == 5)? rd_valid_pipe[5] :
(index == 6)? rd_valid_pipe[6] :
(index == 7)? rd_valid_pipe[7] :
(index == 8)? rd_valid_pipe[8] :
(index == 9)? rd_valid_pipe[9] :
rd_valid_pipe[10];
//synthesis translate_off
//////////////// SIMULATION-ONLY CONTENTS
assign txt_code = (cmd_code == 3'h0)? 24'h4c4d52 :
(cmd_code == 3'h1)? 24'h415246 :
(cmd_code == 3'h2)? 24'h505245 :
(cmd_code == 3'h3)? 24'h414354 :
(cmd_code == 3'h4)? 24'h205752 :
(cmd_code == 3'h5)? 24'h205244 :
(cmd_code == 3'h6)? 24'h425354 :
(cmd_code == 3'h7)? 24'h4e4f50 :
24'h424144;
//////////////// END SIMULATION-ONLY CONTENTS
//synthesis translate_on
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -