//RAM Model
`define RAM_W (256+8-1)
module SDP_RAM (
clock,
data,
rdaddress,
wraddress,
wren,
q);
input clock;
wire clock;
input [7:0] data;
wire [7:0] data;
input [8:0] rdaddress;
wire [8:0] rdaddress;
input [8:0] wraddress;
wire [8:0] wraddress;
input wren;
wire wren;
output [7:0] q;
wire [7:0] q;
reg [7:0] mem[`RAM_W:0];
reg [7:0] sft_1;
reg [7:0] sft_0;
// RAMライト
always
@( posedge clock )
begin :PR_MEM_W
if (wren == 1'b1)
begin
mem[wraddress] <=data[7:0];
end
end
// RAMリード
always
@( posedge clock )
begin :PR_MEM_R
begin
sft_1 <= sft_0;
sft_0 <= mem[rdaddress];
end
end
assign q = sft_1;
endmodule
2010年11月24日水曜日
2010年8月20日金曜日
Verilog-HDL always @()構文
| 項 | イベント式 | 意味 |
|---|---|---|
| 1 | @(posedge signal1 or negedge signal2) | signal1が立ち上がった 又は signal2が立ち下った場合に begin ~ end内を実行 |
| 2 | @(signal1 or signal2) | signal1 又は signal2に変化があった場合に begin ~ end内を実行 |
- クロックとリセットでの記述例は always @(posedge clk or negedge xrst) となる。
- 非同期リセットはレベルで動作するので negedge xrst には違和感があるが、negedgeを外して記述すると両エッジで動作してしまうし、この場合clkの立ち上がりの動作との区別が付かない。その為この記述になる。
Verilog-HDL for/while/repeat文の例
// for/while/repeat文の例
function parity
input [7:0] data;
reg [3:0] sum;
integer i;
begin
sum = 0;
//for文で記述
for(i=0; i<8; i=i+1) begin
sum = sum + data[i];
end
//while文で記述
// while(i<8) begin
// sum = sum + data[i];
// i = i+1;
// end
//repeat文で記述
// repeat(8) begin
// sum = sum + data[i];
// i = i+1;
// end
parity = sum[0];
end
endfunction
function parity
input [7:0] data;
reg [3:0] sum;
integer i;
begin
sum = 0;
//for文で記述
for(i=0; i<8; i=i+1) begin
sum = sum + data[i];
end
//while文で記述
// while(i<8) begin
// sum = sum + data[i];
// i = i+1;
// end
//repeat文で記述
// repeat(8) begin
// sum = sum + data[i];
// i = i+1;
// end
parity = sum[0];
end
endfunction
Verilog-HDL function記述
・Verilog HDLで組み合わせ回路を記述するのにifやcase文を使用する場合、ファンクションとして別に定義する必要がある。
・C言語でいう関数に相当する。
・always記述も可能。
・ファンクション内で一時的に使用するローカル信号はreg宣言したものを使用する。
・ファンクションの入力信号を省略すると大変!
・入力信号と返却値のビット幅には要注意!
・引数の記述順はfunction内での入力信号定義順!
//呼び出し側
assign out = mux(sel,in0,in1,in2,in3);//入力信号全て記述のコト!!
//マルチプレクサ(case文記述)
function [3:0] mux;
input [1:0] sl;
input [3:0] d0,d1,d2,d3;
begin
case(sel)
0 : mux=d0;
1 : mux=d1;
2 : mux=d2;
3 : mux=d3;
default : mux=4'bxxxx;
endcase
end
endfunction
//マルチプレクサ(if文記述)
function [3:0] mux;
input [1:0] sl;
input [3:0] d0,d1,d2,d3;
begin
if(sel==0) mux=d0;
else if(sel==1) mux=d1;
else if(sel==2) mux=d2;
else if(sel==3) mux=d3;
else mux=4'bxxxx;
end
endfunction
・C言語でいう関数に相当する。
・always記述も可能。
・ファンクション内で一時的に使用するローカル信号はreg宣言したものを使用する。
・ファンクションの入力信号を省略すると大変!
・入力信号と返却値のビット幅には要注意!
・引数の記述順はfunction内での入力信号定義順!
//呼び出し側
assign out = mux(sel,in0,in1,in2,in3);//入力信号全て記述のコト!!
//マルチプレクサ(case文記述)
function [3:0] mux;
input [1:0] sl;
input [3:0] d0,d1,d2,d3;
begin
case(sel)
0 : mux=d0;
1 : mux=d1;
2 : mux=d2;
3 : mux=d3;
default : mux=4'bxxxx;
endcase
end
endfunction
//マルチプレクサ(if文記述)
function [3:0] mux;
input [1:0] sl;
input [3:0] d0,d1,d2,d3;
begin
if(sel==0) mux=d0;
else if(sel==1) mux=d1;
else if(sel==2) mux=d2;
else if(sel==3) mux=d3;
else mux=4'bxxxx;
end
endfunction
Verilog-HDL 条件演算子でマルチプレクサ
// 4to1のマルチプレクサを条件演算子で記述
assign out = (sel==0)? in0:
(sel==1)? in1:
(sel==2)? in2:
(sel==3)? in3: 4'bx
assign out = (sel==0)? in0:
(sel==1)? in1:
(sel==2)? in2:
(sel==3)? in3: 4'bx
Verilog-HDL モジュール定義の骨格
module モジュール名称 (ポートリスト);
input 入力信号名;
output 出力信号名;
inout 双方向信号名;
wire 内部信号名;
reg 内部信号名;
パラメータ宣言
ポート宣言
モジュール内信号定義
function宣言
インスタンシエーション
assign文
always文
initial文 ※
endmodule
※論理合成の対象外
input 入力信号名;
output 出力信号名;
inout 双方向信号名;
wire 内部信号名;
reg 内部信号名;
パラメータ宣言
ポート宣言
モジュール内信号定義
function宣言
インスタンシエーション
assign文
always文
initial文 ※
endmodule
※論理合成の対象外
2010年8月17日火曜日
Verilog-HDL 演算子
| 記号 | 演算 | 論理合成 |
|---|---|---|
| + | 加算 | ○ |
| - | 減算 | ○ |
| * | 乗算 | △ |
| / | 除算 | △ |
| % | 剰余 | △ |
| ** | べき乗 | △ |
| 記号 | 演算 | 論理合成 |
|---|---|---|
| < | 小なり | ○ |
| <= | 小なりイコール | ○ |
| > | 大なり | ○ |
| >= | 大なりイコール | ○ |
| 記号 | 演算 | 論理合成 |
|---|---|---|
| == | 一致 | ○ |
| != | 不一致 | ○ |
| === | 一致(X,Zも含む) | × |
| !== | 不一致(X,Zも含む) | × |
| 記号 | 演算 | 論理合成 |
|---|---|---|
| << | 論理左シフト | ○ |
| >> | 論理右シフト | ○ |
| <<< | 算術左シフト | ○※ |
| >>> | 算術右シフト | ○※ |
| 記号 | 演算 | 論理合成 |
|---|---|---|
| ! | 論理否定 | ○ |
| && | 論理積 | ○ |
| || | 論理和 | ○ |
| 記号 | 演算 | 論理合成 |
|---|---|---|
| ~ | NOT | ○ |
| & | AND | ○ |
| | | OR | ○ |
| ^ | EXOR | ○ |
| ~^ | EXNOR | ○ |
| 記号 | 演算 | 論理合成 |
|---|---|---|
| & | AND | ○ |
| ~& | NAND | ○ |
| | | OR | ○ |
| ~| | NOR | ○ |
| ^ | EXOR | ○ |
| ~^ | EXNOR | ○ |
例えば8ビット幅の信号Aの全ビットが1である事をチェックするためには、次の様なAND演算の式になる。
A[7] & A[6] & A[5] & A[4] & A[3] & A[2] & A[1] & A[0];
これをリダクション演算子を使うと
&A;
とシンプルに記述が可能。記号はビット演算子を同じであり文脈から判断される。
| 記号 | 演算 | 論理合成 |
|---|---|---|
| ? : | 条件演算 | ○ |
| { } | 連結演算 | ○ |
| 優先順位 | 演算子 |
|---|---|
| 高い | ! & ~& | ~| ^ ~^ + - (単項演算) |
| * / % | |
| + - | |
| << >> <<< >>> | |
| < <= > >= | |
| == != === !=== | |
| & ~& ~ ~^ | |
| | ~| | |
| && | |
| || | |
| 低い | ? : |
Verilog-HDL 基本文法
■識別子
・信号や定数モジュール名、パラメータ等につける名前のこと
・アルファベット、数字、_(アンダースコア)、$(ダラー)が使用可能
・識別子の先頭はアルファベットかアンダースコア
・予約語は使えない
■論理値
0:論理0
1:論理1
Z または z :ハイ・インピーダンス
X または x :不定値
■数値表現
ビット数'基数に続き数値
4'b0101 4ビット バイナリ 0101
16'sh12AB 符号付 16ビット ヘキサ 12AB(Verilog2001)
123 32ビット 10進数 123
・10進数は不定やハイインピーダンス指定が出来ない
・読みやすさ向上のため任意の場所を _ で区切ると良い
・ビット長表記が無いと32ビットとして処理
■wire
・ネット型データ(信号)
wire xrst, clk; //2つの異なる名前のwire型信号
wire [7:0] dat1, dat2;//8本のバス状信号から成るwire型信号2組
・ビットフィールド
wire [15:0] dat; //と宣言されているとして
dat[0] //datの0ビット目1本の信号
dat[15:8] //datの15~8の8本の信号
dat //datの16本の信号全体
■reg
・レジスタ型データ(信号)
宣言とビットフィールドについてはwireをregに読みかえて同じ
・信号や定数モジュール名、パラメータ等につける名前のこと
・アルファベット、数字、_(アンダースコア)、$(ダラー)が使用可能
・識別子の先頭はアルファベットかアンダースコア
・予約語は使えない
■論理値
0:論理0
1:論理1
Z または z :ハイ・インピーダンス
X または x :不定値
■数値表現
ビット数'基数に続き数値
4'b0101 4ビット バイナリ 0101
16'sh12AB 符号付 16ビット ヘキサ 12AB(Verilog2001)
123 32ビット 10進数 123
・10進数は不定やハイインピーダンス指定が出来ない
・読みやすさ向上のため任意の場所を _ で区切ると良い
・ビット長表記が無いと32ビットとして処理
■wire
・ネット型データ(信号)
wire xrst, clk; //2つの異なる名前のwire型信号
wire [7:0] dat1, dat2;//8本のバス状信号から成るwire型信号2組
・ビットフィールド
wire [15:0] dat; //と宣言されているとして
dat[0] //datの0ビット目1本の信号
dat[15:8] //datの15~8の8本の信号
dat //datの16本の信号全体
■reg
・レジスタ型データ(信号)
宣言とビットフィールドについてはwireをregに読みかえて同じ
2010年7月28日水曜日
Verilog-HDL シミュレーション結果保存テンプレート
//=======================
// 結果をファイルに保存
//=======================
integer mcd;
initial mcd = $fopen("D:/Project/ABC/tp00_dmp.txt");
reg file_strb ; // ストローブポイントモニタ
always begin
file_strb = 0;
#(STEP*0.9);
file_strb = 1;
$fdisplay(mcd,"%b %b %b %b %h %h %b %h",
top_sim_01.CS_SPI, top_sim_01.SCK_SPI, top_sim_01.MO_SPI,
REG_IRQ, REG_READDATA,
top_sim_01.ADDRESS_DPRAM, top_sim_01.WREN_DPRAM, top_sim_01.WRDATA_DPRAM);
#(STEP*0.1);
end
// 結果をファイルに保存
//=======================
integer mcd;
initial mcd = $fopen("D:/Project/ABC/tp00_dmp.txt");
reg file_strb ; // ストローブポイントモニタ
always begin
file_strb = 0;
#(STEP*0.9);
file_strb = 1;
$fdisplay(mcd,"%b %b %b %b %h %h %b %h",
top_sim_01.CS_SPI, top_sim_01.SCK_SPI, top_sim_01.MO_SPI,
REG_IRQ, REG_READDATA,
top_sim_01.ADDRESS_DPRAM, top_sim_01.WREN_DPRAM, top_sim_01.WRDATA_DPRAM);
#(STEP*0.1);
end
RAMモデルのシミュレーション
Modelsim-Altera でのシミュレーション手順
- プロジェクト作成
- .vファイル登録(RAMを自作モデル→メガファンクション出力モデルに差し替え)
- コンパイル
- Start Simulation
- Librariesタグで altera_mf_ver をロード ※1
- Designタグで所望のデザインを選択後 OKボタン
登録:
投稿 (Atom)