📄 odt_watchdog.v
字号:
end
3'd1: begin
wr_cmd_count_en[1] <= 1;
wr_cmd_counter[1] <= 1;
wr_ddr_cs_n_d[1] <= ddr_cs_n;
end
3'd2: begin
wr_cmd_count_en[2] <= 1;
wr_cmd_counter[2] <= 1;
wr_ddr_cs_n_d[2] <= ddr_cs_n;
end
3'd3: begin
wr_cmd_count_en[3] <= 1;
wr_cmd_counter[3] <= 1;
wr_ddr_cs_n_d[3] <= ddr_cs_n;
end
3'd4: begin
wr_cmd_count_en[4] <= 1;
wr_cmd_counter[4] <= 1;
wr_ddr_cs_n_d[4] <= ddr_cs_n;
end
3'd5: begin
wr_cmd_count_en[5] <= 1;
wr_cmd_counter[5] <= 1;
wr_ddr_cs_n_d[5] <= ddr_cs_n;
end
3'd6: begin
wr_cmd_count_en[6] <= 1;
wr_cmd_counter[6] <= 1;
wr_ddr_cs_n_d[6] <= ddr_cs_n;
end
3'd7: begin
wr_cmd_count_en[7] <= 1;
wr_cmd_counter[7] <= 1;
wr_ddr_cs_n_d[7] <= ddr_cs_n;
end
endcase
end
///////////////////////////////////////////////////////////////////////
// Count the clocks for a read command
for (i=0; i<8; i=i+1) begin
if (cmd_count_en[i])
cmd_counter[i] <= cmd_counter[i] + 1;
if (int_burst_len == 4 && (cmd_counter[i] == (cas_lat+add_lat-1))) begin
cmd_counter[i] <= 0;
cmd_count_en[i] <= 0;
end
else if (int_burst_len == 8 && (cmd_counter[i] == (cas_lat+add_lat+1))) begin
cmd_counter[i] <= 0;
cmd_count_en[i] <= 0;
end
end
// Count the clocks for a write command
for (i=0; i<8; i=i+1) begin
if (wr_cmd_count_en[i])
wr_cmd_counter[i] <= wr_cmd_counter[i] + 1;
if (int_burst_len == 4 && (wr_cmd_counter[i] == (cas_lat+add_lat-2))) begin
wr_cmd_counter[i] <= 0;
wr_cmd_count_en[i] <= 0;
end
else if (int_burst_len == 8 && (wr_cmd_counter[i] == (cas_lat+add_lat))) begin
wr_cmd_counter[i] <= 0;
wr_cmd_count_en[i] <= 0;
end
end
end
///////////////////////////////////////////////////////////////////////
// Detect the ODT assertion and flag an error if ODT was not found asserted.
reg [`CS_WIDTH-1:0] flop_ddr_odt;
always @ (posedge mem_clk or negedge rst_n) begin
if (!rst_n) begin
flop_ddr_odt <= 'b0;
end
else begin
flop_ddr_odt <= ddr_odt;
end
end
`ifdef CS_WIDTH_2
always @ (posedge mem_clk) begin
if (mem_rd_cmd) begin
`ifdef USR_SLOT_SIZE_1
`else
// edge 0 should sample ODT asserted
if ((cas_lat + add_lat) == 3) begin
if (ddr_cs_n == 2'b01 && !ddr_odt[0])
$display ("ODT ERROR: ddr_odt[0] should be high at time %0t\n",$time);
if (ddr_cs_n == 2'b10 && !ddr_odt[1])
$display ("ODT ERROR: ddr_odt[1] should be high at time %0t\n",$time);
end
`endif
end
//----------------------------------------------------------
if (mem_wr_cmd) begin
`ifdef USR_SLOT_SIZE_1
if ((cas_lat + add_lat) < 5) begin
if (!ddr_odt[0])
$display ("ODT ERROR: ddr_odt[0] should be high at time %0t\n",$time);
end
`else
// edge 0 should sample ODT asserted
if ((cas_lat + add_lat) < 5) begin
if (ddr_cs_n == 2'b01 && !ddr_odt[0])
$display ("ODT ERROR: ddr_odt[0] should be high at time %0t\n",$time);
if (ddr_cs_n == 2'b10 && !ddr_odt[1])
$display ("ODT ERROR: ddr_odt[1] should be high at time %0t\n",$time);
end
`endif
`ifdef USR_SLOT_SIZE_1
if ((cas_lat + add_lat) == 3) begin
if (!flop_ddr_odt[0])
$display ("ODT ERROR: ddr_odt[0] should have been high a clock cycle earlier at time %0t\n",$time);
end
`else
// edge -1 should have sampled ODT asserted
if ((cas_lat + add_lat) == 3) begin
if (ddr_cs_n == 2'b01 && !flop_ddr_odt[0])
$display ("ODT ERROR: ddr_odt[0] should have been high a clock cycle earlier at time %0t\n",$time);
if (ddr_cs_n == 2'b10 && !flop_ddr_odt[1])
$display ("ODT ERROR: ddr_odt[1] should have been high a clock cycle earlier at time %0t\n",$time);
end
`endif
end
//----------------------------------------------------------
// ODT detection for read commands
`ifdef USR_SLOT_SIZE_1
`else
for (i=0; i<8; i=i+1) begin
if (cmd_count_en[i] && int_burst_len == 4 && (cas_lat == 3) &&
(cmd_counter[i] >= add_lat) && (cmd_counter[i] < (cas_lat+add_lat-1))) begin
if (ddr_cs_n_d[i] == 2'b01 && !ddr_odt[0])
$display ("ODT ERROR: ddr_odt[0] should be high at time %0t\n",$time);
if (ddr_cs_n_d[i] == 2'b10 && !ddr_odt[1])
$display ("ODT ERROR: ddr_odt[1] should be high at time %0t\n",$time);
end
else if (cmd_count_en[i] && int_burst_len == 4 && (cas_lat == 4) &&
(cmd_counter[i] >= add_lat+1) && (cmd_counter[i] < (cas_lat+add_lat-1))) begin
if (ddr_cs_n_d[i] == 2'b01 && !ddr_odt[0])
$display ("ODT ERROR: ddr_odt[0] should be high at time %0t\n",$time);
if (ddr_cs_n_d[i] == 2'b10 && !ddr_odt[1])
$display ("ODT ERROR: ddr_odt[1] should be high at time %0t\n",$time);
end
if (cmd_count_en[i] && int_burst_len == 8 && (cas_lat == 3) &&
(cmd_counter[i] >= add_lat) && (cmd_counter[i] < (cas_lat+add_lat+1))) begin
if (ddr_cs_n_d[i] == 2'b01 && !ddr_odt[0])
$display ("ODT ERROR: ddr_odt[0] should be high at time %0t\n",$time);
if (ddr_cs_n_d[i] == 2'b10 && !ddr_odt[1])
$display ("ODT ERROR: ddr_odt[1] should be high at time %0t\n",$time);
end
else if (cmd_count_en[i] && int_burst_len == 8 && (cas_lat == 4) &&
(cmd_counter[i] >= add_lat+1) && (cmd_counter[i] < (cas_lat+add_lat+1))) begin
if (ddr_cs_n_d[i] == 2'b01 && !ddr_odt[0])
$display ("ODT ERROR: ddr_odt[0] should be high at time %0t\n",$time);
if (ddr_cs_n_d[i] == 2'b10 && !ddr_odt[1])
$display ("ODT ERROR: ddr_odt[1] should be high at time %0t\n",$time);
end
end
`endif
//----------------------------------------------------------
// ODT detection for write commands
`ifdef USR_SLOT_SIZE_1
for (i=0; i<8; i=i+1) begin
if (wr_cmd_count_en[i] && (int_burst_len == 4) && (cas_lat == 3) &&
(wr_cmd_counter[i] >= add_lat-1) && (wr_cmd_counter[i] < (cas_lat+add_lat-2))) begin
if (!ddr_odt[0])
$display ("ODT ERROR: ddr_odt[0] should be high at time %0t\n",$time);
end
else if (wr_cmd_count_en[i] && (int_burst_len == 4) && (cas_lat == 4) &&
(wr_cmd_counter[i] >= add_lat) && (wr_cmd_counter[i] < (cas_lat+add_lat-2))) begin
if (!ddr_odt[0])
$display ("ODT ERROR: ddr_odt[0] should be high at time %0t\n",$time);
end
if (wr_cmd_count_en[i] && (int_burst_len == 8) && (cas_lat == 3) &&
(wr_cmd_counter[i] >= add_lat-1) && (wr_cmd_counter[i] < (cas_lat+add_lat))) begin
if (!ddr_odt[0])
$display ("ODT ERROR: ddr_odt[0] should be high at time %0t\n",$time);
end
else if (wr_cmd_count_en[i] && int_burst_len == 8 && (cas_lat == 4) &&
(wr_cmd_counter[i] >= add_lat) && (wr_cmd_counter[i] < (cas_lat+add_lat))) begin
if (!ddr_odt[0])
$display ("ODT ERROR: ddr_odt[0] should be high at time %0t\n",$time);
end
end
`else
for (i=0; i<8; i=i+1) begin
if (wr_cmd_count_en[i] && (int_burst_len == 4) && (cas_lat == 3) &&
(wr_cmd_counter[i] >= add_lat-1) && (wr_cmd_counter[i] < (cas_lat+add_lat-2))) begin
if (wr_ddr_cs_n_d[i] == 2'b01 && !ddr_odt[0])
$display ("ODT ERROR: ddr_odt[0] should be high at time %0t\n",$time);
if (wr_ddr_cs_n_d[i] == 2'b10 && !ddr_odt[1])
$display ("ODT ERROR: ddr_odt[1] should be high at time %0t\n",$time);
end
else if (wr_cmd_count_en[i] && (int_burst_len == 4) && (cas_lat == 4) &&
(wr_cmd_counter[i] >= add_lat) && (wr_cmd_counter[i] < (cas_lat+add_lat-2))) begin
if (wr_ddr_cs_n_d[i] == 2'b01 && !ddr_odt[0])
$display ("ODT ERROR: ddr_odt[0] should be high at time %0t\n",$time);
if (wr_ddr_cs_n_d[i] == 2'b10 && !ddr_odt[1])
$display ("ODT ERROR: ddr_odt[1] should be high at time %0t\n",$time);
end
if (wr_cmd_count_en[i] && (int_burst_len == 8) && (cas_lat == 3) &&
(wr_cmd_counter[i] >= add_lat-1) && (wr_cmd_counter[i] < (cas_lat+add_lat))) begin
if (wr_ddr_cs_n_d[i] == 2'b01 && !ddr_odt[0])
$display ("ODT ERROR: ddr_odt[0] should be high at time %0t\n",$time);
if (wr_ddr_cs_n_d[i] == 2'b10 && !ddr_odt[1])
$display ("ODT ERROR: ddr_odt[1] should be high at time %0t\n",$time);
end
else if (wr_cmd_count_en[i] && int_burst_len == 8 && (cas_lat == 4) &&
(wr_cmd_counter[i] >= add_lat) && (wr_cmd_counter[i] < (cas_lat+add_lat))) begin
if (wr_ddr_cs_n_d[i] == 2'b01 && !ddr_odt[0])
$display ("ODT ERROR: ddr_odt[0] should be high at time %0t\n",$time);
if (wr_ddr_cs_n_d[i] == 2'b10 && !ddr_odt[1])
$display ("ODT ERROR: ddr_odt[1] should be high at time %0t\n",$time);
end
end
`endif
if (!(|wr_cmd_count_en) && !(|cmd_count_en) && |ddr_odt && ((cas_lat+add_lat) > 4))
$display ("ODT ERROR: ddr_odt asserted when it should not be at time %0t\n",$time);
end
`endif
`ifdef CS_WIDTH_1
// When only one module is controlled, the ODT pin should be asserted
// during write operations and de-asserted during read.
always @ (posedge mem_clk) begin
for (i=0; i<8; i=i+1) begin
if (wr_cmd_count_en[i] && (int_burst_len == 4) && (cas_lat > 3 ) &&
//(wr_cmd_counter[i] >= add_lat) && (wr_cmd_counter[i] < (cas_lat+add_lat-2))) begin
(wr_cmd_counter[i] >= (cas_lat + add_lat -4)) && (wr_cmd_counter[i] < (cas_lat+add_lat-2))) begin
if (!ddr_odt)
$display ("ODT ERROR: ddr_odt should be high at time %0t\n",$time);
end
else if (wr_cmd_count_en[i] && int_burst_len == 4 && ( cas_lat == 3 ) &&
//(wr_cmd_counter[i] >= add_lat) && (wr_cmd_counter[i] < (cas_lat+add_lat-2))) begin
(wr_cmd_counter[i] >= add_lat) && (wr_cmd_counter[i] < (cas_lat+add_lat-2))) begin
if (!ddr_odt)
$display ("ODT ERROR: ddr_odt should be high at time %0t\n",$time);
end
if (wr_cmd_count_en[i] && int_burst_len == 8 && (cas_lat > 3 ) &&
//(wr_cmd_counter[i] >= add_lat) && (wr_cmd_counter[i] < (cas_lat+add_lat))) begin
(wr_cmd_counter[i] >= (add_lat + cas_lat -2)) && (wr_cmd_counter[i] < (cas_lat+add_lat))) begin
if (!ddr_odt)
$display ("ODT ERROR: ddr_odt should be high at time %0t\n",$time);
end
else if (wr_cmd_count_en[i] && int_burst_len == 8 && ( cas_lat == 3 ) &&
//(wr_cmd_counter[i] >= add_lat) && (wr_cmd_counter[i] < (cas_lat+add_lat))) begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -