📄 mt46v4m16.vhd
字号:
(Burst_length_4 = '1' AND Count_precharge(2) >= 5) OR
(Burst_length_8 = '1' AND Count_precharge(2) >= 7)) THEN
Pc_b2 := '1';
Act_b2 := '0';
RP_chk2 := NOW;
Auto_precharge(2) := '0';
Write_precharge(2) := '0';
END IF;
END IF;
IF ((Auto_precharge(3) = '1') AND (Write_precharge(3) = '1') AND (NOW - RAS_chk3 >= tRAS)) THEN
IF ((Burst_length_2 = '1' AND Count_precharge(3) >= 4) OR
(Burst_length_4 = '1' AND Count_precharge(3) >= 5) OR
(Burst_length_8 = '1' AND Count_precharge(3) >= 7)) THEN
Pc_b3 := '1';
Act_b3 := '0';
RP_chk3 := NOW;
Auto_precharge(3) := '0';
Write_precharge(3) := '0';
END IF;
END IF;
END IF;
-- Internal Precharge or Bst
IF Command(0) = PRECH THEN -- Precharge terminate current read if same bank or all bank
IF Bank_precharge(0) = Bank OR A10_precharge(0) = '1' THEN
IF Data_out_enable = '1' THEN
Dqs_out <= "ZZ";
Data_out_enable := '0';
END IF;
END IF;
ELSIF Command(0) = BST THEN -- Burst terminate current read
IF Data_out_enable = '1' THEN
Dqs_out <= "ZZ";
Data_out_enable := '0';
END IF;
END IF;
WAIT FOR 1 ps; -- Delay for Dqs to go HiZ then accept new internal Dqs
-- Dqs Generator
IF Data_out_enable = '1' THEN
Dqs_int <= "00";
IF Dqs_out = "00" THEN
Dqs_out <= "11";
ELSIF Dqs_out = "11" THEN
Dqs_out <= "00";
ELSE
Dqs_out <= "00";
END IF;
ELSIF Data_out_enable = '0' AND Dqs_int = "00" THEN
Dq <= (OTHERS => 'Z');
Dqs_out <= "ZZ";
END IF;
WAIT FOR 1 ps; -- Delay for Dqs to go HiZ then accept new Read or Write
-- Internal Dqs
IF Command(2) = READ OR Command(2) = READ_A THEN
IF (Data_out_enable = '0') THEN
Dqs_out <= "00";
Dqs_int <= "11";
END IF;
ELSIF (Command(2) = WRITE OR Command(2) = WRITE_A) THEN
Dqs_out <= "ZZ";
Dqs_int <= "00";
END IF;
-- Detect Read or Write Command
Rw_command <= Command(1);
-- Checking internal wires
Pre_chk (0) <= Pc_b0;
Pre_chk (1) <= Pc_b1;
Pre_chk (2) <= Pc_b2;
Pre_chk (3) <= Pc_b3;
Act_chk (0) <= Act_b0;
Act_chk (1) <= Act_b1;
Act_chk (2) <= Act_b2;
Act_chk (3) <= Act_b3;
END PROCESS;
-- Read or Write Command waiting for Dqs
rw_decode : PROCESS
-- Latch Address for Read or Write
PROCEDURE Latch_address IS
BEGIN
Bank_dqs <= Bank_addr (1);
Col_dqs <= Col_addr (1);
Col_brst_dqs <= Col_addr (1);
IF Bank_addr (1) = "00" THEN
Row_dqs <= B0_row_addr;
ELSIF Bank_addr (1) = "01" THEN
Row_dqs <= B1_row_addr;
ELSIF Bank_addr (1) = "10" THEN
Row_dqs <= B2_row_addr;
ELSIF Bank_addr (1) = "11" THEN
Row_dqs <= B3_row_addr;
END IF;
END;
BEGIN
WAIT ON Rw_command;
IF (Rw_command = READ OR Rw_command = READ_A) THEN
Latch_address;
WAIT ON Sys_clk;
Bank <= Bank_dqs;
Row <= Row_dqs;
Col := Col_dqs;
Col_brst <= Col_brst_dqs;
Burst_counter := 0;
Data_in_enable := '0';
Data_out_enable := '1';
ELSIF (Rw_command = WRITE OR Rw_command = WRITE_A) THEN
Latch_address;
WAIT ON Dqs UNTIL Dqs = "11";
Bank <= Bank_dqs;
Row <= Row_dqs;
Col := Col_dqs;
Col_brst <= Col_brst_dqs;
Burst_counter := 0;
Data_in_enable := '1';
Data_out_enable := '0';
END IF;
END PROCESS;
-- Dqs Buffer (Driver / Receiver)
Dqs_buffer : PROCESS
TYPE ram_type IS ARRAY (2**col_bits - 1 DOWNTO 0) OF BIT_VECTOR (data_bits - 1 DOWNTO 0);
TYPE ram_pntr IS ACCESS ram_type;
TYPE ram_stor IS ARRAY (2**addr_bits - 1 DOWNTO 0) OF ram_pntr;
VARIABLE Bank0 : ram_stor;
VARIABLE Bank1 : ram_stor;
VARIABLE Bank2 : ram_stor;
VARIABLE Bank3 : ram_stor;
VARIABLE Row_index, Col_index : INTEGER := 0;
-- Initialize empty rows
PROCEDURE Init_mem (Bank : BIT_VECTOR; Row_index : INTEGER) IS
VARIABLE i, j : INTEGER := 0;
BEGIN
IF Bank = "00" THEN
IF Bank0 (Row_index) = NULL THEN -- Check to see if row empty
Bank0 (Row_index) := NEW ram_type; -- Open new row for access
FOR i IN (2**col_bits - 1) DOWNTO 0 LOOP -- Filled row with zeros
FOR j IN (data_bits - 1) DOWNTO 0 LOOP
Bank0 (Row_index) (i) (j) := '0';
END LOOP;
END LOOP;
END IF;
ELSIF Bank = "01" THEN
IF Bank1 (Row_index) = NULL THEN
Bank1 (Row_index) := NEW ram_type;
FOR i IN (2**col_bits - 1) DOWNTO 0 LOOP
FOR j IN (data_bits - 1) DOWNTO 0 LOOP
Bank1 (Row_index) (i) (j) := '0';
END LOOP;
END LOOP;
END IF;
ELSIF Bank = "10" THEN
IF Bank2 (Row_index) = NULL THEN
Bank2 (Row_index) := NEW ram_type;
FOR i IN (2**col_bits - 1) DOWNTO 0 LOOP
FOR j IN (data_bits - 1) DOWNTO 0 LOOP
Bank2 (Row_index) (i) (j) := '0';
END LOOP;
END LOOP;
END IF;
ELSIF Bank = "11" THEN
IF Bank3 (Row_index) = NULL THEN
Bank3 (Row_index) := NEW ram_type;
FOR i IN (2**col_bits - 1) DOWNTO 0 LOOP
FOR j IN (data_bits - 1) DOWNTO 0 LOOP
Bank3 (Row_index) (i) (j) := '0';
END LOOP;
END LOOP;
END IF;
END IF;
END;
-- Burst Counter
PROCEDURE Burst_decode IS
VARIABLE Col_int : INTEGER := 0;
VARIABLE Col_temp, Col_vec : BIT_VECTOR (col_bits - 1 DOWNTO 0) := (OTHERS => '0');
BEGIN
-- Advance burst counter
Burst_counter := Burst_counter + 1;
-- Burst Type
IF Mode_reg (3) = '0' THEN
Col_int := TO_INTEGER(Col);
Col_int := Col_int + 1;
TO_BITVECTOR (Col_int, Col_temp);
ELSIF Mode_reg (3) = '1' THEN
TO_BITVECTOR (Burst_counter, Col_vec);
Col_temp (2) := Col_vec (2) XOR Col_brst (2);
Col_temp (1) := Col_vec (1) XOR Col_brst (1);
Col_temp (0) := Col_vec (0) XOR Col_brst (0);
END IF;
-- Burst Length
IF Burst_length_2 = '1' THEN
Col(0) := Col_temp (0);
ELSIF Burst_length_4 = '1' THEN
Col(1 DOWNTO 0) := Col_temp (1 DOWNTO 0);
ELSIF Burst_length_8 = '1' THEN
Col(2 DOWNTO 0) := Col_temp (2 DOWNTO 0);
ELSE
Col := Col_temp;
END IF;
-- Data counter
IF Burst_length_2 = '1' THEN
IF Burst_counter >= 2 THEN
IF Data_in_enable = '1' THEN
Data_in_enable := '0';
ELSIF Data_out_enable = '1' THEN
Data_out_enable := '0';
END IF;
END IF;
ELSIF Burst_length_4 = '1' THEN
IF Burst_counter >= 4 THEN
IF Data_in_enable = '1' THEN
Data_in_enable := '0';
ELSIF Data_out_enable = '1' THEN
Data_out_enable := '0';
END IF;
END IF;
ELSIF Burst_length_8 = '1' THEN
IF Burst_counter >= 8 THEN
IF Data_in_enable = '1' THEN
Data_in_enable := '0';
ELSIF Data_out_enable = '1' THEN
Data_out_enable := '0';
END IF;
END IF;
END IF;
END;
BEGIN
WAIT ON Dqs;
WAIT FOR 1 ps; -- Delay to avoid race condition with Rw_command
Row_index := TO_INTEGER (Row);
Col_index := TO_INTEGER (Col);
IF Data_in_enable = '1' THEN
IF Dm = "00" THEN
Init_mem (Bank, Row_index);
IF Bank = "00" THEN
Bank0 (Row_index) (Col_index) := TO_BITVECTOR (Dq);
ELSIF Bank = "01" THEN
Bank1 (Row_index) (Col_index) := TO_BITVECTOR (Dq);
ELSIF Bank = "10" THEN
Bank2 (Row_index) (Col_index) := TO_BITVECTOR (Dq);
ELSIF Bank = "11" THEN
Bank3 (Row_index) (Col_index) := TO_BITVECTOR (Dq);
END IF;
WR_chk (TO_INTEGER(Bank)) := 0;
END IF;
Burst_decode;
ELSIF Data_out_enable = '1' THEN
Init_mem (Bank, Row_index);
IF Bank = "00" THEN
Dq <= TO_STDLOGICVECTOR (Bank0 (Row_index) (Col_index));
ELSIF Bank = "01" THEN
Dq <= TO_STDLOGICVECTOR (Bank1 (Row_index) (Col_index));
ELSIF Bank = "10" THEN
Dq <= TO_STDLOGICVECTOR (Bank2 (Row_index) (Col_index));
ELSIF Bank = "11" THEN
Dq <= TO_STDLOGICVECTOR (Bank3 (Row_index) (Col_index));
END IF;
Burst_decode;
ELSE
Dq <= (OTHERS => 'Z');
END IF;
END PROCESS;
-- Setup timing checks
Setup_check : PROCESS
BEGIN
WAIT ON Sys_clk;
IF Sys_clk = '1' THEN
ASSERT(Cke'LAST_EVENT >= tIS)
REPORT "CKE Setup time violation -- tIS"
SEVERITY WARNING;
ASSERT(Cs_n'LAST_EVENT >= tIS)
REPORT "CS# Setup time violation -- tIS"
SEVERITY WARNING;
ASSERT(Cas_n'LAST_EVENT >= tIS)
REPORT "CAS# Setup time violation -- tIS"
SEVERITY WARNING;
ASSERT(Ras_n'LAST_EVENT >= tIS)
REPORT "RAS# Setup time violation -- tIS"
SEVERITY WARNING;
ASSERT(We_n'LAST_EVENT >= tIS)
REPORT "WE# Setup time violation -- tIS"
SEVERITY WARNING;
ASSERT(Addr'LAST_EVENT >= tIS)
REPORT "ADDR Setup time violation -- tIS"
SEVERITY WARNING;
ASSERT(Ba'LAST_EVENT >= tIS)
REPORT "BA Setup time violation -- tIS"
SEVERITY WARNING;
END IF;
END PROCESS;
-- Hold timing checks
Hold_check : PROCESS
BEGIN
WAIT ON Sys_clk'DELAYED (tIH);
IF Sys_clk'DELAYED (tIH) = '1' THEN
ASSERT(Cke'LAST_EVENT >= tIH)
REPORT "CKE Setup time violation -- tIH"
SEVERITY WARNING;
ASSERT(Cs_n'LAST_EVENT >= tIH)
REPORT "CS# Setup time violation -- tIH"
SEVERITY WARNING;
ASSERT(Cas_n'LAST_EVENT >= tIH)
REPORT "CAS# Setup time violation -- tIH"
SEVERITY WARNING;
ASSERT(Ras_n'LAST_EVENT >= tIH)
REPORT "RAS# Setup time violation -- tIH"
SEVERITY WARNING;
ASSERT(We_n'LAST_EVENT >= tIH)
REPORT "WE# Setup time violation -- tIH"
SEVERITY WARNING;
ASSERT(Addr'LAST_EVENT >= tIH)
REPORT "ADDR Setup time violation -- tIH"
SEVERITY WARNING;
ASSERT(Ba'LAST_EVENT >= tIH)
REPORT "BA Setup time violation -- tIH"
SEVERITY WARNING;
END IF;
END PROCESS;
END behave;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -