⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 monitor.v

📁 DDR2 的控制器
💻 V
📖 第 1 页 / 共 5 页
字号:
                    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 + -