Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Языки VHDL и VERILOG в проектировании цифровой аппаратуры
.pdf
Глава 7. Функциональная модель микросхемы двухпортовой памяти 241
time tCCS ;// 5_000; // min
///////////////INITIAL FOR DEVICE TYPE TIME PARAM////////
initial begin
tDelta=0;
if( `DeviceType == 83)
dev_type= 1;
else if ( `DeviceType ==67)
dev_type= 2;
else
$display("TB ERROR- defined WRONG DEVICE TYPE");
tCYC2 = tCYC2_arr[dev_type] ; //12_000; // min =
tCH2 = tCH2_arr [dev_type] ;// // min
tCL2= tCL2_arr[dev_type] ;// // min
tSA= tSA_arr[dev_type] ;// // min =
tHA = tHA_arr[dev_type] ;// // min=0ns
//OUT DEL
tCD2= tCD2_arr [dev_type] ;// // max =
tDC= tDC_arr [dev_type] ;// // min
tCKLZ= tCKLZ_arr[dev_type] ;// // min
tCKHZ= tCKHZ_arr [dev_type] ; // // min
tOE= tOE_arr [dev_type] ;// // min
tOLZ= tOLZ_arr [dev_type] ;// // min
tOHZ= tOHZ_arr[dev_type] ;// // min
tCCS= tCCS_arr[dev_type] ;// // min
end
/////////////END OF INITIALISATION OF TIME PARAM//////////
// полезные константы-------------------------------reg [`data_length-1 :0 ] HIZ ;initial HIZ = {`data_length{1'bz}};
reg [`data_length-1 :0 ] HIX ;initial HIX = {`data_length{1'bx}};
reg [`addr_length-1 :0 ] HIZA;initial HIZA = {`addr_length{1'bz}};
reg [`addr_length-1 :0 ] HIXA;initial HIXA = {`addr_length{1'bx}};
// common cycle var
integer i,j,k;
/////////////////////////////////////////////////////
// ТАКТОВЫЙ ГЕНЕРАТОР-CLOCK GEN*******
reg pclk;
//pclk_gen
initial begin
pclk =0;
forever begin
#(tCL2 -tDelta);
pclk <= ~pclk;
#(tCYC2-tCL2-tDelta);
pclk <= ~pclk;
end
end
reg [31:0] tDIF;
initial tDIF=`tDel_clk_x2y ;// initial val clock to clock delay
assign clkl=pclk;
assign #tDIF clkr=pclk;
//end clk gen**********************************************

242 Глава 7. Функциональная модель микросхемы двухпортовой памяти
7.6.2. ПРОЦЕДУРЫ ЗАПИСИ-ЧТЕНИЯ
**************************************
reg [`data_length-1:0] iol, ior;
integer test_number;
initial
begin
iol =HIZ; ior =HIZ;
ar =HIZA; al =HIZA;
test_number=0;
end
integer error;
// TEST HEADER MSG TASK------------------------------------task TEST_HEAD_MSG;
input [31*8-1:0] test_name; //------------input [31*8-1:0] expected_res;
begin
test_number= test_number+1;
$display ("\nTime =%0t.START Test_number %0d.",$time,test_number);
$display (" TEST_NAME %0s ",test_name);
$display ("Expected results: %0s \n",expected_res);
end
endtask
//-----ПРОЦЕДУРЫ ЗАПИСИ В ЛЕВЫЙ ПОРТ -WRITE TASKS------//запись кажые 2 такта
task LEFT_PORT_WRITE input [`addr_length-1:0] ADDR;
input [`data_length-1:0] DATA;
integer i;
begin
@(posedge clkl);
#(tCYC2 - (tSA - tDelta)); //tSAetup
oel_n =1; // output disable
ce0l_n =0; ce1l =1; //chip enable
rwl =0; //write
al = ADDR;
iol = DATA;
@(posedge clkl);
if (`debug == 1)
$display ("Time =%0t.Ver:LEFT port WRITE : addr=%h,data=%h,busval=%h",
$time, al,iol,iol_w );
#(tHA - tDelta); //thold #500;
rwl =1;
al =HIZA; iol =HIZ;
ce0l_n =1; ce1l =0; //chip disable
//@(posedge clkl);
//delay for eliminate CEL_n delayed to 2 clk=1 for next posible read!
end
endtask
//процедура записи группы слов на каждом такте
task L_PORT_FAST_WRITE;//--
input [31:0] start_num;
input [31:0] num;

Глава 7. Функциональная модель микросхемы двухпортовой памяти 243
reg [`addr_length-1:0] ADDR;
reg [`data_length-1:0] DATA;
integer n;
integer i;
begin
@(posedge clkl);
$display ("\nTime =%0t. START TASK Left port fast write \n", $time);
#(tCYC2 - (tSA - tDelta)); //tsetup
oel_n =1; // output disable
ce0l_n =0; ce1l =1; //chip enable
rwl =0; //write
ADDR=start_num;
// ADDR={17'b0,1'bx};
DATA=start_num;
al = ADDR;
iol = DATA;
for (i=start_num; i<=start_num+num-2;i=i+1)begin
@(posedge clkl);
if (`debug == 1)
$display ("T =%0t.Ver:Lport WRITE : addr=%h,data=%h, bus==%h",
$time, al,iol,iol_w );
#(tHA - tDelta); //thold #500;
al =HIXA;
iol =HIX;
ce0l_n =1; ce1l =0; //chip disable
#(tCYC2 -(tHA -tDelta)- (tSA - tDelta)); //tsetup
ce0l_n =0; ce1l =1; //chip enable
ADDR=ADDR+1; DATA=DATA+1;
al = ADDR; iol = DATA;
end // END FOR
@(posedge clkl);
if (`debug == 1)
$display ("T =%0t.Ver:L port WRITE LAST WORD : addr=%h,data=%h.",
$time, al,iol );
#(tHA - tDelta); //thold #500;
al =HIZA;iol =HIZ;
ce0l_n =1; ce1l =0; //chip disable
end
endtask
//--------------------READ -TASKS------------------READ
//Процедуры чтения
// чтение одного слова
task LEFT_PORT_READ;
input [`addr_length-1:0] ADDR;
input [`data_length-1:0] DATA;
begin
@(posedge clkl);
#(tCYC2 - (tSA - tDelta)); //tsetap address tS
ce0l_n =0; ce1l =1; //chip enable
oel_n =0; // output enable
rwl =1; //read
al = ADDR;

244 Глава 7. Функциональная модель микросхемы двухпортовой памяти
@(posedge clkl);
#(tHA - tDelta); // thold address tHA
rwl =1; al =HIZA;
ce0l_n =1; ce1l =0; //chip disable ??
@(posedge clkl);
@(posedge clkl);
//@(posedge clkl);
//#(tCD2+100);
if(DATA === iol_w)begin
if (`debug == 1)
$display ("Time =%0t.Ver:Left port read: addr=%h,data=%h.",
$time, ADDR,iol_w );
end
else begin
error =1;
$display ("T =%0t.ERR:Ver:L port read: addr=%h,data=%h, exp.data=%h.",
$time, ADDR,iol_w,DATA );
end
end
endtask
//чтение группы слов на каждом такте
// с возможной вставкой одной записи и
// отключением выхода памяти
task L_PORT_READ_WRITE;//-----------------FAST READ -WRITE
// READ with possibility of WRITE and out disable
input [31:0] start_num; // начальный адрес
input [31:0] num; //число слов > 2
input [31:0] w_num; // номер ячейки в которую пойдет запись 1 слова
// если мы этого не хотим-задаем этот номер > num
input [31:0] oe_num; // номер ячейки для которой oe отключает выход
// памяти на 1 такт
// когда мы этого не желаем задаем его > num
input [31:0] tSETUP_OE; // задержка начала отключения OE по отношению к clk
input [31:0] tHOLD_OE;
input comp; //когда параметр ==1 не производится
// сравнение выхода с эталоном
reg [`addr_length-1:0] ADDR;
reg [`data_length-1:0] DATA;
integer n;
time toex_posedge;integer i;
reg oe_controlled; reg write_was;
reg [31:0] write_num; reg[31:0] oe_dis_num;
begin
// тело опущено
////////////////////////// end of tasks ////////////////////////
//-------------------------------------**************************************
always @( error)
if (error == 1)
begin
$display ("\nTime =%0t.TEST STOPPED - ERROR.Check messages above.",$time);
repeat(10) @(posedge clkl);
$stop;

Глава 7. Функциональная модель микросхемы двухпортовой памяти 245
7.6.3. Подача тестовых векторов
//////////НИЖЕ ЗАДАНИЕ ТЕСТА test sequence ////////////////////////////////////
integer test_num; // number of test case, convinent to include in waveform
reg [8*20:0] test_name;// name of test case, convinent to include in waveform
//integer i, j;
reg [2:0] b_lng;
initial
begin #1;
//$dumpvars;
//$recordvars;
error =0; i =0; j =0;
rwl =1; rwr =1; oel_n=1; oer_n =1;
ce0l_n =1; ce1l = 0; ce0r_n =1; ce1r =0;
// SIMPLE TESTS 1-4 WITH CE and OE don't READING CASES---------------TEST_HEAD_MSG (" #1 Left port fast write","TO addr 1-10 write data 1-10");
L_PORT_FAST_WRITE(1,10 );//!!
// L_PORT_FAST_WRITE(HIXA,10 );
TEST_HEAD_MSG (" #2 Left port fast READ"," read data 1-10 from addr 1-10");
L_PORT_FAST_READ(1,10,4,8,3*tSA,tHA,1 );
TEST_HEAD_MSG (" #3 RIGHT port fast write","TO addr 11-20 write data 11-20");
R_PORT_FAST_WRITE(11,10 );
TEST_HEAD_MSG (" #4 RIGHT port fast READ","read from addr 11-20,cs and OE ");
// test_num =101; //------------// test_name="RIGHT port fast READ";
// $display ("\nTime =%0t. Test #101. RIGHT port fast READ \n", $time);
R_PORT_FAST_READ(11,10,14,18,3*tSA,tHA,1 );
//-------------------TWO -BANK TESTS- 5-9----------------------
TEST_HEAD_MSG (" #5 Left port fast write with bank 1 to 2 changing");
L_PORT_FAST_WRITE(18'h3FFFE,10 );
TEST_HEAD_MSG (" #6 Left port fast READ with bank 1 to 2 changing “ );
L_PORT_FAST_READ(18'h3FFFE,10,0,0,0,0,1 );
TEST_HEAD_MSG (" #7 Right port fast write with bank 1 to 2 changing");
R_PORT_FAST_WRITE(18'h3FFFA,10 );
TEST_HEAD_MSG (" #8 Right port fast READ with bank 1 to 2 changing ");
R_PORT_FAST_READ(18'h3FFFA,10,0,0,0,0,1 );
// --чтение-запись вперемежку с отдельного порта ----//READ TO WRITE TO READ --------------------
test_num =1001; //------------test_name="Left port READ-to-write";
$display ("\nTime =%0t. Test #1001. Left port READ -WRITE\n", $time);
$display ("after READ 2 words EXPECTED NO OP cycle WRITING 1 word=3 to addr 3");
// set word 3 to 0
LEFT_PORT_WRITE(3,0);
L_PORT_READ_WRITE (1,10,3,20,tSA,tHA,1 );
//check writing 3 to addr 3
L_PORT_FAST_READ(1,10,0,0,0,0,1 );
test_num =1002; //------------test_name="Left port READ-to-write";
$display ("\nTime =%0t. Test #1002. Left port READ -WRITE\n", $time);
$display ("после чтения 2 ожидается запись 1 слова по адресу 3 ");
LEFT_PORT_WRITE(3,0);//сначала 0 в ячейку с адресом 3
L_PORT_READ_WRITE (1,10,3,3,3*tSA,tHA,1 );//чтение с прерыванием на запись

246 Глава 7. Функциональная модель микросхемы двухпортовой памяти
//проверка – что по адресу 3 на самом деле ? 3?
L_PORT_FAST_READ(1,10,0,0,0,0,1 );
test_num =1003; //------------test_name="Right port READ-to-write";
$display ("\nTime =%0t. Test #1003. Right port READ -WRITE\n", $time);
$display ("after READ 2 words EXPECTED NO OPERATION cycle WRITING 1 word");
// set word 3 to 0
RIGHT_PORT_WRITE(3,0);
R_PORT_READ_WRITE (1,10,3,20,tSA,tHA,1 );
//check writing to addr 3
R_PORT_FAST_READ(1,10,0,0,0,0,1 );
test_num =1004; //------------test_name="Right port READ-to-write";
$display ("\nTime =%0t. Test #1004. Right port READ -WRITE\n", $time);
$display ("after READ 2 words EXPECTED OE CONTROLLED WRITING 1 word ");
// set word 3 to 0
RIGHT_PORT_WRITE(3,0);
R_PORT_READ_WRITE (1,10,3,3,3*tSA,tHA,1 );
//check writing to addr 3
R_PORT_FAST_READ(1,10,0,0,0,0,1 );
//----------------------------------------------------
test_num =105; //------------test_name="BANK SELECT READ";
$display ("\nTime =%0t. Test #105.BANK SELECT READ \n", $time);
$display ("EXPECTED CHANGE DATA OUT STREAM FROM BANK1 TO BANK 2");
L_PORT_FAST_READ(18'h3FFFE,10,20,20,0,0,1 );
test_num =106; //------------test_name="LPORT:R-to-W-to-R,OE=0";
$display ("\nTime =%0t. Test #106. LPORT:R-to-W-to-R,OE=0\n", $time);
$display ("EXPECTED NO OPERATION cycle");
fork
begin L_PORT_FAST_READ(1,3,20,20,0,0,0 );// 5 clk duration
repeat (1)@(posedge clkl);
L_PORT_FAST_READ(1,3,20,20,0,0,0 );
end
begin repeat(3) @(posedge clkl); L_PORT_FAST_WRITE(3,1 );
repeat(5) @(posedge clkl);
end
join
test_num =107; //------------test_name="LPORT:R-to-W-to-R,OE controlled";
$display ("\nTime =%0t. Test #106. LPORT:R-to-W-to-R,OE controlled\n", $time);
fork
begin L_PORT_FAST_READ(1,3,20,20,0,0,0 );//5 clk
repeat (1)@(posedge clkl);
L_PORT_FAST_READ(1,3,20,20,0,0,0 );
end
begin repeat(5) @(posedge clkl); L_PORT_FAST_WRITE(1,1 );
repeat(5) @(posedge clkl);
end
join
// Параллельная работа портов
test_num =102; //-------------

Глава 7. Функциональная модель микросхемы двухпортовой памяти 247
test_name="CONCURENT Left-RIGHT ports fast write";
$display ("\nTime =%0t. Test #102. Lw-Rw CONCURENT\n", $time);
$display ("EXPECTED CONFLICT MSG AND X VAL TO THE MEM 10 words");
fork
L_PORT_FAST_WRITE(1,10 );
R_PORT_FAST_WRITE(1,10 );
join
test_num =1011; //------------test_name="RIGHT port fast READ";
$display ("\nTime =%0t. Test #1011. RIGHT port fast READ \n", $time);
$display ("EXPECTED X VAL from THE MEM 10 words,but comparator disabled ");
R_PORT_FAST_READ(1,10,20,20,0,0,0 );
test_num =103; //------------test_name=" Left-read RIGHT-write CONCUR ";
$display ("\nTime =%0t. Test #103. Lr;Rw CONCURENT \n", $time);
$display ("CONFLICT MSG AND X VAL from MEM 10 words, comparator disabled");
fork
L_PORT_FAST_READ(1,10,20,20,0,0,0 );
R_PORT_FAST_WRITE(1,10 );
join
test_num =104; //------------test_name=" Left-write RIGHT-read CONCUR";
$display ("\nTime =%0t. Test #104. Lw;Rr CONCURENT \n", $time);
$display (" NO conflict because when clk collision, waddr/= raddr");
fork
R_PORT_FAST_READ(1,10,20,20,0,0,1 );
L_PORT_FAST_WRITE(1,10 );
join
// end concurent tests
test_num =2; //-------------
test_name="Left port write";
$display ("\nTime =%0t. Test #2. Left port write \n", $time);
for (i=0; i<=13;i=i+1) // 131071
begin LEFT_PORT_WRITE(i,i); end
repeat(20) @(posedge clkl);
test_num =3;//------------------
test_name="Left port read";
$display ("\nTime =%0t. Test #3. Left port read . \n", $time);
for (i=0; i<=13;i=i+1) //131071
begin LEFT_PORT_READ (i,i); end
test_num =4; //-------------------
test_name="Left port write/read sequent";
$display ("\nTime =%0t. Test #4. Left port write/read sequent . \n", $time);
for (i=0; i<=10;i=i+1)
begin
LEFT_PORT_WRITE(i,i); LEFT_PORT_READ (i,i);
end
test_num =5;
test_name="right port write";
$display ("\nTime =%0t. Test #5. RIGHT port write . \n", $time);
for (i=11; i<=22;i=i+1)
begin RIGHT_PORT_WRITE(i,i); end
repeat(20) @(posedge clkl);

248 Глава 7. Функциональная модель микросхемы двухпортовой памяти
test_num =55; //------------test_name="right port fast write";
$display ("\nTime =%0t. Test #55. Right port fast write \n", $time);
R_PORT_FAST_WRITE(1,10 );
test_num =6;
test_name="right port read";
$display ("\nTime =%0t. Test #6. RIGHT port read . \n", $time);
for (i=11; i<=22;i=i+1)
begin
RIGHT_PORT_READ (i,i);
end
test_num =7;
test_name=" RIGHT port write/read sequent";
$display ("\nTime =%0t. Test #7. RIGHT port write/read sequent . \n", $time);
for (i=23; i<=35;i=i+1)
begin
RIGHT_PORT_WRITE(i,i); RIGHT_PORT_READ (i,i);
end
/*
test_num =8;
test_name="Concurrent write/read from ports ";
$display ("\nTime =%0t. Test #8. Concurrent write/read from ports . \n", $time);
for (i=23; i<=35;i=i+1)
begin
fork
LEFT_PORT_WRITE (i,i);
RIGHT_PORT_WRITE (i,i);
LEFT_PORT_WRITE (i,i);
join
fork
RIGHT_PORT_READ (i,i);
LEFT_PORT_READ (i,i);
join
end
*/
test_num =9;
test_name=" Left port write and RIGHT port read sequent";
$display ("\nTime =%0t Test #9.Left port write and RIGHT port read seq \n",
$time);
for (i=50; i<=80;i=i+1)
begin
LEFT_PORT_WRITE(i,i); RIGHT_PORT_READ (i,i);
end
test_num =10;
test_name="RIGHT port write and LEFT port read sequent";
$display ("\nTime =%0t Test #10.RIGHT port write and LEFT port read seq.\n",
$time);
for (i=81; i<=100;i=i+1)
begin
RIGHT_PORT_WRITE(i,i); LEFT_PORT_READ (i,i);
end
test_num =11;
$display ("\nTime =%0tTest #11.RIGHT port write fast and LEFT port read \n",

Глава 7. Функциональная модель микросхемы двухпортовой памяти 249
$time);
repeat (20) @(posedge clkl); // delay to change clkl
fork
for (i=101; i<=200;i=i+1) RIGHT_PORT_WRITE(i,i);
for (j=101; j<=200;j=j+1) LEFT_PORT_READ (j,j);
join
repeat (5) @(posedge clkl); // delay to change delay betwin clk
// clkl leader
// start collision---------------------
tDIF=1000;
repeat (5) @(posedge clkr); // delay to change delay betwin clk
test_num =13;
$display ("\nTime =%0t. Test #13. CONCURENT ports write with collision . \n", $time);
fork
for (i=201; i<=210;i=i+1) RIGHT_PORT_WRITE(i,i);
for (j=201; j<=210;j=j+1) LEFT_PORT_WRITE(j,j);
join
repeat (5) @(posedge clkl);
test_num =14;
$display ("\nTime =%0t Test #14.COnC RP- wr and LP read with collision. \n",
$time);
fork
for (i=211; i<=220;i=i+1) RIGHT_PORT_WRITE(i,i);
for (j=211; j<=220;j=j+1) LEFT_PORT_READ(j,j);
join
repeat (5) @(posedge clkl);
test_num =15;
$display ("\nT =%0t Test #15. CONC RP read and LP write with collision. \n",
$time);
fork
for (i=211; i<=230;i=i+1) RIGHT_PORT_READ(i,i);
for (j=211; j<=230;j=j+1) LEFT_PORT_WRITE(j,j);
join
///////////////////////////////////////////
if(error)begin
$display ("\nTime =%0t. ERROR: Test FAILED. See messages above.\n",
$time);
end
else begin
$display ("\n***************************************************");
$display ("\nTime =%0t. : Test PASSED.\n", $time);
$display ("*****************************************************************");
// $finish;
$stop;
end
end
////////////////////////// test sequence finish ////////////////
//-----------------------------------------**************************************
// --НИЖЕ КОНКРЕТИЗАЦИИ ,блоков ПАМЯТИ -----------------------------assign iol_w=iol;assign ior_w=ior;
assign iol_w2=iol;assign ior_w2=ior;
assign iol_w3=iol;assign ior_w3=ior;
//chip selection by using msf addr bit

250 Глава 7. Функциональная модель микросхемы двухпортовой памяти
wire addr_msfl= al[`addr_length-1 ];
wire addr_msfr= ar[`addr_length-1 ];
wire ce0l_n_bank1,ce0l_n_bank2;
assign ce0l_n_bank1=(addr_msfl==0)?ce0l_n:1;
assign ce0l_n_bank2=(addr_msfl==1)?ce0l_n:1;
wire ce0r_n_bank1,ce0r_n_bank2;
assign ce0r_n_bank1=(addr_msfr==0)?ce0r_n:1;
assign ce0r_n_bank2=(addr_msfr==1)?ce0r_n:1;
/// vhdl модели банков памяти!
// банк 1- модель VHDL
\dual_port_ramv_vh bank1 (
al_bank, ar_bank,// ar ,
rwl, rwr, // rwr ,
oel_n, oer_n, // oer_n ,
iol_w, ior_w, // ior ,
clkl , clkr,// clkr ,
ce0l_n_bank1, ce1l,// ce1l ,
ce0r_n_bank1, ce1r // ce1r
);
/// vhdl – банк 2 модель VHDL
\dual_port_ramv_vh bank2 (
al_bank, ar_bank,// ar ,
rwl, rwr, // rwr ,
oel_n, oer_n, // oer_n ,
iol_w, ior_w, // ior ,
clkl, clkr,// clkr ,
ce0l_n_bank2 ce1l,// ce1l ,
ce0r_n_bank2, ce1r // ce1r
);
/// verilog модели
//áàíê 1
dual_port_ramv bank1_ver (
.AL(al_bank), .AR(ar_bank),// ar ,
.RWL(rwl), .RWR(rwr), // rwr ,
.OEL_n(oel_n), .OER_n(oer_n), // oer_n ,
.IOL(iol_w2), .IOR(ior_w2), // ior ,
.CLKL(clkl), .CLKR(clkr),// clkr ,
.CE0L_n(ce0l_n_bank1),.CE1L(ce1l),// ce1l ,
.CE0R_n(ce0r_n_bank1), .CE1R(ce1r) // ce1r
);
//áàíê 2
dual_port_ramv bank2_ver (
.AL( al_bank), .AR(ar_bank),// ar ,
.RWL(rwl), .RWR(rwr), // rwr ,
.OEL_n(oel_n), .OER_n(oer_n), // oer_n ,
.IOL(iol_w2), .IOR(ior_w2), // ior ,
.CLKL(clkl), .CLKR(clkr),// clkr ,
.CE0L_n(ce0l_n_bank2), .CE1L(ce1l),// ce1l ,
.CE0R_n(ce0r_n_bank2), .CE1R(ce1r) // ce1r
);
endmodule
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
