# PATTERN
###### tags: `Digital IC Design`
[回到主頁面](https://hackmd.io/@derek8955/BkK2Nb5Jo/https%3A%2F%2Fhackmd.io%2FdpcBlBL8TlShpQ-wSi9Quw)
### <font color="blue"> Stimulus (測試資料) </font>
- 撰寫測資有兩種策略:
- Directed Testing : 透過人工的方式將輸入與輸出的情形寫下來
- Random Testing ( prefer ) : 隨機產生
- 撰寫測資有兩種方法:
- Verilog : 直接寫在 PATTERN 裡面
- High level language ( prefer ) : python、matlab...等。在外部先 run 一遍,將輸入與輸出的結果存下來,在 PATTERN 內將檔案讀入
> 高階程式語言彈性比較高,而且不會有 overflow 的問題。
### <font color="blue"> Read file </font>
只要會其中一種即可,還有很多種方式,以下只列一小部分。
:::success
test.txt
10101101 00011101 01101111 01100001
00000001 11111110 11111111 11101110
:::
```verilog=
reg [7:0] data_in;
// open file
file = $fopen("test.txt","r");
// read data from specific file
$fscanf(file,"%d",data_in);
// 可以指定輸入格式
// 以空白或跨行為斷點
// data_in = 10101101
$fscanf(file,"%d",data_in);
// data_in = 00011101
$fscanf(file,"%d",data_in);
// data_in = 01101111
```
```verilog=
reg [7:0] in[0:7];
// read data from specific file
$readmemb("test.txt",in);
// 同樣可以指定輸入格式
// 讀取 2 進制的資料。一行 code 就會把所有檔案內的資料 copy 到 in 。
// in 自然也須被設定為 array 才能一次存放多筆資料
// in[0] = 10101101, in[1] = 00011101,以此類推
```
### <font color="blue"> Delay </font>
```verilog=
initial begin
#10 a = 0; // 等待10個 unit
#5 a = 1;
@(negedge clk) // 等待 clk 負緣到來
wait(a === 1); // 等待 a 為 1 的情況才接續執行。
$finish;
end
```
:::warning
PATTERN 需要考慮四種 logic value( [見 04 - data types](https://hackmd.io/@derek8955/BkK2Nb5Jo/https%3A%2F%2Fhackmd.io%2FPUFV4TJWR46sFqgljeOOJA) ),所以等於運算子必須使用 === 或 !==
:::
### <font color="blue"> Generate clock & reset </font>
- Asynchronous reset
```verilog=
`define CYCLE = 10.0;
module PATTERN;
reg clk, rst_n;
initial clk = 0;
always #(CYCLE/2.0) clk = ~clk; // duty cycle = 50%
initial begin
rst_n = 1’b1;
force clk =0; // 強迫 clk 為 0
#(0.5); rst_n= 1’b0;
#(10); rst_n= 1’b1;
#(3); release clk; // 釋放 clk
// delay time 要設多少就根據自己而定
end
endmodule
```
### <font color="blue"> Verify output </font>
```verilog=
`define N_PAT = 100;
module PATTERN();
...
...
...
initial begin
$readmemh( "GoldenOut.txt", golden_out);
patcount = 0; err = 0;
end
always @(posedge CLK) begin
if ( output_valid ) begin
current_out = golden_out[patcount];
if ( data_out !== current_out) begin
$display("ERROR at %d : output %h, expect %h", patcount, data_out, current_out);
err = err + 1 ;
end
patcount = patcount + 1 ;
end
if( patcount == N_PAT ) begin
if ( err == 0 ) begin
$display ("--------------------------------------");
$display (" Congratulations! ");
$display (" You have passed all patterns ");
$display (" ");
$display ("--------------------------------------");
end
else $display(" Total errors : ", err);
$finish;
end
end
```
### <font color="blue"> Task and Function </font>
- 選擇一個方式即可,但因為 task 裡的電路是可以包含 delay 資訊,所以一般在 PATTERN 內都是用 task
```verilog=
module PATTERN;
reg [4:0] a;
reg [4:0] b;
initial begin
a = 30;
add( a, b );
// b = 50
$finish;
end
task add;
input [4:0] in;
output [5:0] out;
begin
out = in + 20 ;
end
endtask
endmodule
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
module PATTERN;
reg [4:0] a;
reg [4:0] b;
initial begin
a = 30;
add;
// b = 50
$finish;
end
task add;
begin
b = a + 20 ;
end
endtask
endmodule
```