📄 monitor.v
字号:
end
endcase
`endif
`ifdef CS_WIDTH_1
case (ddr_cs_n)
1'b0,
1'b1 : begin
end
default : begin
if (mem_pre_cmd && ~ddr_ad[10])
$display ("MON ERROR: Illegal chip select at time %0t\n",$time);
end
endcase
`endif
end
end
end // always @ (posedge clk) begin
///////////////////////////////////////////////////////////////////////
// Logic that monitors the commands at the memory interface and checks whether
// precharge and/or activate command should be issued based on the
// bank management logic. This logic is closely linked with the
// assertion of chip selects.
reg [13:0] row_table[0:31];
reg [31:0] bnksts_tab; //1: open, 0:closed
reg [31:0] rowtab_en;
reg [7:0] cs_n;
reg bnksts_tab_out;
integer rt;
integer bt;
assign mem_aref_cmd = ~(&ddr_cs_n) & ddr_cke &
~ddr_ras_n & ~ddr_cas_n & ddr_we_n;
// determine the expected chip select based on the bank address provided by
// the user.
`ifdef INT_BANK_8
// Only four chip selects possible
always @ (fifo_out_bank) begin
case(fifo_out_bank[4:3])
2'b00 : cs_n = 8'b1111_1110;
2'b01 : cs_n = 8'b1111_1101;
2'b10 : cs_n = 8'b1111_1011;
2'b11 : cs_n = 8'b1111_0111;
endcase
end
`else
always @ (fifo_out_bank) begin
case(fifo_out_bank[4:2])
3'b000 : cs_n = 8'b1111_1110;
3'b001 : cs_n = 8'b1111_1101;
3'b010 : cs_n = 8'b1111_1011;
3'b011 : cs_n = 8'b1111_0111;
3'b100 : cs_n = 8'b1110_1111;
3'b101 : cs_n = 8'b1101_1111;
3'b110 : cs_n = 8'b1011_1111;
3'b111 : cs_n = 8'b0111_1111;
endcase
end
`endif
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
bnksts_tab <= 32'b0;
for (rt=0;rt<32;rt=rt+1) begin
row_table[rt] <= 32'b0;
end
end
else begin
// compare the actual chip selects with the expected value.
`ifdef ECP_20_ONLY
if ((mem_rd_cmd_3d_new) || (mem_wr_cmd_3d)) begin
`else
if ((mem_rd_cmd_d) || (mem_wr_cmd_d)) begin
`endif
`ifdef CS_WIDTH_8
if (ddr_cs_n_d != cs_n)
$display ("MON ERROR: Chip select mismatch at time %0t. Expected %0h, Actual %0h\n", $time, cs_n, ddr_cs_n_d);
`endif
`ifdef CS_WIDTH_4
if (ddr_cs_n_d != cs_n[3:0])
$display ("MON ERROR: Chip select mismatch at time %0t. Expected %0h, Actual %0h\n", $time, cs_n[3:0], ddr_cs_n_d);
`endif
`ifdef CS_WIDTH_2
if (ddr_cs_n_d != cs_n[1:0])
$display ("MON ERROR: Chip select mismatch at time %0t. Expected %0h, Actual %0h\n", $time, cs_n[1:0], ddr_cs_n_d);
`endif
`ifdef CS_WIDTH_1
if (ddr_cs_n_d != cs_n[0])
$display ("MON ERROR: Chip select mismatch at time %0t. Expected %0h, Actual %0h\n", $time, cs_n[0], ddr_cs_n_d);
`endif
end
// when a lmr or auto refresh command is issued, set all
// banks to close state.
if (mem_aref_cmd || mem_lmr_cmd || mem_sref_cmd) begin
bnksts_tab <= 32'b0;
end
// update the row table and bank status table when an activate
// or precharge command is seen on the memory interface
for (bt=0;bt<32;bt=bt+1) begin
if (mem_act_cmd && rowtab_en[bt]) begin
row_table[bt] <= ddr_ad;
bnksts_tab[bt] <= 1'b1;
end
else if ((mem_pre_cmd && rowtab_en[bt]) ||
((mem_wr_cmd || mem_rd_cmd) && ddr_ad[10])) begin
bnksts_tab[bt] <= 1'b0;
end
end
// When ever an activate command is issued, check the row address
// to determine whether the command should have been received.
if (mem_act_cmd && bnksts_tab_out) // The row was open
$display ("MON ERROR: Activate command issued for an open bank at time %0t\n",$time);
// When a precharge command is issued, check the row address
// to determine whether the command should have been received.
//if (mem_pre_cmd && !bnksts_tab_out) // The row was closed
//$display ("MON INFO: Precharge command issued for a closed bank at time %0t\n",$time);
end
end
// generate the enable signal to write into a specific row table location.
always @ (ddr_cs_n or ddr_ba) begin
`ifdef INT_BANK_8
if (~(&ddr_cs_n) && ((ddr_ba[2] === 1'bx) || (ddr_ba[1] === 1'bx) ||
(ddr_ba[0] === 1'bx))) begin
$display ("MON ERROR: Unknown values on ddr_ba = %d signal at time %0t\n",ddr_ba, $time);
end
`else
if (~(&ddr_cs_n) && ((ddr_ba[1:0] != 2'b00) && (ddr_ba[1:0] != 2'b01) &&
(ddr_ba[1:0] != 2'b10) && (ddr_ba[1:0] != 2'b11))) begin
$display ("MON ERROR: Unknown values on ddr_ba signal at time %0t\n",$time);
end
`endif
rowtab_en = 32'b0;
`ifdef INT_BANK_8
case ({ddr_cs_n, ddr_ba})
7'b1110_000 : rowtab_en[0] = 1;
7'b1110_001 : rowtab_en[1] = 1;
7'b1110_010 : rowtab_en[2] = 1;
7'b1110_011 : rowtab_en[3] = 1;
7'b1110_100 : rowtab_en[4] = 1;
7'b1110_101 : rowtab_en[5] = 1;
7'b1110_110 : rowtab_en[6] = 1;
7'b1110_111 : rowtab_en[7] = 1;
7'b1101_000 : rowtab_en[8] = 1;
7'b1101_001 : rowtab_en[9] = 1;
7'b1101_010 : rowtab_en[10] = 1;
7'b1101_011 : rowtab_en[11] = 1;
7'b1101_100 : rowtab_en[12] = 1;
7'b1101_101 : rowtab_en[13] = 1;
7'b1101_110 : rowtab_en[14] = 1;
7'b1101_111 : rowtab_en[15] = 1;
7'b1011_000 : rowtab_en[16] = 1;
7'b1011_001 : rowtab_en[17] = 1;
7'b1011_010 : rowtab_en[18] = 1;
7'b1011_011 : rowtab_en[19] = 1;
7'b1011_100 : rowtab_en[20] = 1;
7'b1011_101 : rowtab_en[21] = 1;
7'b1011_110 : rowtab_en[22] = 1;
7'b1011_111 : rowtab_en[23] = 1;
7'b0111_000 : rowtab_en[24] = 1;
7'b0111_001 : rowtab_en[25] = 1;
7'b0111_010 : rowtab_en[26] = 1;
7'b0111_011 : rowtab_en[27] = 1;
7'b0111_100 : rowtab_en[28] = 1;
7'b0111_101 : rowtab_en[29] = 1;
7'b0111_110 : rowtab_en[30] = 1;
7'b0111_111 : rowtab_en[31] = 1;
default : rowtab_en = 0;
`else
case ({ddr_cs_n, ddr_ba[1:0]})
10'b11111110_00 : rowtab_en[0] = 1;
10'b11111110_01 : rowtab_en[1] = 1;
10'b11111110_10 : rowtab_en[2] = 1;
10'b11111110_11 : rowtab_en[3] = 1;
10'b11111101_00 : rowtab_en[4] = 1;
10'b11111101_01 : rowtab_en[5] = 1;
10'b11111101_10 : rowtab_en[6] = 1;
10'b11111101_11 : rowtab_en[7] = 1;
10'b11111011_00 : rowtab_en[8] = 1;
10'b11111011_01 : rowtab_en[9] = 1;
10'b11111011_10 : rowtab_en[10] = 1;
10'b11111011_11 : rowtab_en[11] = 1;
10'b11110111_00 : rowtab_en[12] = 1;
10'b11110111_01 : rowtab_en[13] = 1;
10'b11110111_10 : rowtab_en[14] = 1;
10'b11110111_11 : rowtab_en[15] = 1;
10'b11101111_00 : rowtab_en[16] = 1;
10'b11101111_01 : rowtab_en[17] = 1;
10'b11101111_10 : rowtab_en[18] = 1;
10'b11101111_11 : rowtab_en[19] = 1;
10'b11011111_00 : rowtab_en[20] = 1;
10'b11011111_01 : rowtab_en[21] = 1;
10'b11011111_10 : rowtab_en[22] = 1;
10'b11011111_11 : rowtab_en[23] = 1;
10'b10111111_00 : rowtab_en[24] = 1;
10'b10111111_01 : rowtab_en[25] = 1;
10'b10111111_10 : rowtab_en[26] = 1;
10'b10111111_11 : rowtab_en[27] = 1;
10'b01111111_00 : rowtab_en[28] = 1;
10'b01111111_01 : rowtab_en[29] = 1;
10'b01111111_10 : rowtab_en[30] = 1;
10'b01111111_11 : rowtab_en[31] = 1;
10'b11111111_00 : rowtab_en = 0;
10'b11111111_01 : rowtab_en = 0;
10'b11111111_10 : rowtab_en = 0;
10'b11111111_11 : rowtab_en = 0;
`endif
endcase
end
// Based on the address given out by the controller, select the bank status bit
// Based on the address given out by the controller, select the bank status bit
always @ (ddr_cs_n or ddr_ba or bnksts_tab) begin
`ifdef INT_BANK_8
case ({ddr_cs_n, ddr_ba})
7'b1110_000 : bnksts_tab_out = bnksts_tab[0];
7'b1110_001 : bnksts_tab_out = bnksts_tab[1];
7'b1110_010 : bnksts_tab_out = bnksts_tab[2];
7'b1110_011 : bnksts_tab_out = bnksts_tab[3];
7'b1110_100 : bnksts_tab_out = bnksts_tab[4];
7'b1110_101 : bnksts_tab_out = bnksts_tab[5];
7'b1110_110 : bnksts_tab_out = bnksts_tab[6];
7'b1110_111 : bnksts_tab_out = bnksts_tab[7];
7'b1101_000 : bnksts_tab_out = bnksts_tab[8];
7'b1101_001 : bnksts_tab_out = bnksts_tab[9];
7'b1101_010 : bnksts_tab_out = bnksts_tab[10];
7'b1101_011 : bnksts_tab_out = bnksts_tab[11];
7'b1101_100 : bnksts_tab_out = bnksts_tab[12];
7'b1101_101 : bnksts_tab_out = bnksts_tab[13];
7'b1101_110 : bnksts_tab_out = bnksts_tab[14];
7'b1101_111 : bnksts_tab_out = bnksts_tab[15];
7'b1011_000 : bnksts_tab_out = bnksts_tab[16];
7'b1011_001 : bnksts_tab_out = bnksts_tab[17];
7'b1011_010 : bnksts_tab_out = bnksts_tab[18];
7'b1011_011 : bnksts_tab_out = bnksts_tab[19];
7'b1011_100 : bnksts_tab_out = bnksts_tab[20];
7'b1011_101 : bnksts_tab_out = bnksts_tab[21];
7'b1011_110 : bnksts_tab_out = bnksts_tab[22];
7'b1011_111 : bnksts_tab_out = bnksts_tab[23];
7'b0111_000 : bnksts_tab_out = bnksts_tab[24];
7'b0111_001 : bnksts_tab_out = bnksts_tab[25];
7'b0111_010 : bnksts_tab_out = bnksts_tab[26];
7'b0111_011 : bnksts_tab_out = bnksts_tab[27];
7'b0111_100 : bnksts_tab_out = bnksts_tab[28];
7'b0111_101 : bnksts_tab_out = bnksts_tab[29];
7'b0111_110 : bnksts_tab_out = bnksts_tab[30];
7'b0111_111 : bnksts_tab_out = bnksts_tab[31];
endcase
`else
case ({ddr_cs_n, ddr_ba})
10'b11111110_00 : bnksts_tab_out = bnksts_tab[0];
10'b11111110_01 : bnksts_tab_out = bnksts_tab[1];
10'b11111110_10 : bnksts_tab_out = bnksts_tab[2];
10'b11111110_11 : bnksts_tab_out = bnksts_tab[3];
10'b11111101_00 : bnksts_tab_out = bnksts_tab[4];
10'b11111101_01 : bnksts_tab_out = bnksts_tab[5];
10'b11111101_10 : bnksts_tab_out = bnksts_tab[6];
10'b11111101_11 : bnksts_tab_out = bnksts_tab[7];
10'b11111011_00 : bnksts_tab_out = bnksts_tab[8];
10'b11111011_01 : bnksts_tab_out = bnksts_tab[9];
10'b11111011_10 : bnksts_tab_out = bnksts_tab[10];
10'b11111011_11 : bnksts_tab_out = bnksts_tab[11];
10'b11110111_00 : bnksts_tab_out = bnksts_tab[12];
10'b11110111_01 : bnksts_tab_out = bnksts_tab[13];
10'b11110111_10 : bnksts_tab_out = bnksts_tab[14];
10'b11110111_11 : bnksts_tab_out = bnksts_tab[15];
10'b11101111_00 : bnksts_tab_out = bnksts_tab[16];
10'b11101111_01 : bnksts_tab_out = bnksts_tab[17];
10'b11101111_10 : bnksts_tab_out = bnksts_tab[18];
10'b11101111_11 : bnksts_tab_out = bnksts_tab[19];
10'b11011111_00 : bnksts_tab_out = bnksts_tab[20];
10'b11011111_01 : bnksts_tab_out = bnksts_tab[21];
10'b11011111_10 : bnksts_tab_out = bnksts_tab[22];
10'b11011111_11 : bnksts_tab_out = bnksts_tab[23];
10'b10111111_00 : bnksts_tab_out = bnksts_tab[24];
10'b10111111_01 : bnksts_tab_out = bnksts_tab[25];
10'b10111111_10 : bnksts_tab_out = bnksts_tab[26];
10'b10111111_11 : bnksts_tab_out = bnksts_tab[27];
10'b01111111_00 : bnksts_tab_out = bnksts_tab[28];
10'b01111111_01 : bnksts_tab_out = bnksts_tab[29];
10'b01111111_10 : bnksts_tab_out = bnksts_tab[30];
10'b01111111_11 : bnksts_tab_out = bnksts_tab[31];
endcase
`endif
end
///////////////////////////////////////////////////////////////////////
// Logic that ensures that the number of read and write commands presented at
// the user interface matches with the number seen on the memory interface.
integer usr_read_cnt, mem_read_cnt;
integer usr_write_cnt, mem_write_cnt;
integer wr_cmd_clkcnt, rd_cmd_clkcnt;
reg mon_endoftest;
// Read command: cs=0, ras=1, cas=0, we=1
// Write command: cs=0, ras=1, cas=0, we=0
assign mem_rd_cmd = ~(&ddr_cs_n) & ddr_ras_n & ~ddr_cas_n & ddr_we_n;
assign mem_wr_cmd = ~(&ddr_cs_n) & ddr_ras_n & ~ddr_cas_n & ~ddr_we_n;
initial begin
mon_endoftest = 0;
end
`ifdef SLAYER
wire clk_1;
assign #1 clk_1 = clk;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -