寫在前面
VHDL是一門硬體語言,沒學過硬體語言,挺感興趣,還可以用在計組的實驗中,花了點時間學習整理了一下VHDL的基本語法,方便查看,本blog所用到的所有圖片都參考自
VHDL語言的基本語法參考檔案
一、VHDL語言的基本語法
1、VHDL語言的表示符


2、VHDL的數字
2.1 數字型文字
156E2的意思是156
×
\times
×
1
0
2
10^2
102;
下劃線可以連接數字,

2.2 數字基數表示的文字

2.3 字串型文字



2.4 下標名及下標段名


downto 和 to 有什么區別
舉個例子,比如要生命一個長度位8的vector的信號
Signal s1: std_logic_vector(7 downto 0); 這個形成的陣列下標值從右到左依次是7,6,5,4,3,2,1,0
Signal s2: std_logic_vector(0 to 7);這個形成的陣列的下標值從右到做依次是0,1,2,3,4,5,6,7
所以區別就是顯示方向不同而已,
二、VHDL語言的資料物件
1、常數


2、變數



3、信號(SIGNAL)





三、VHDL中的資料型別


1、VHDL的預定義資料型別

1.1 布爾(BOOLEAN)

1.2 位(BIT)

1.3 位矢量(BIT_VECTOR)

1.4 字符(CHARACHTER)

1.5 整數(INTEGER)


1.6 實數(REAL)

1.7 字串(STRING)

1.8 時間(TIME)資料型別

1.9 錯誤等級(SEVERITY_LEVEL)

2、IEEE預定義標準邏輯位與矢量

2.1 標準邏輯位STD_LOGIN資料型別


2.2 標準邏輯矢量(STD_LOGIC_VECTOR)

2.3 其他預定義標準資料型別


(1) 無符號資料型別(UNSIGNED TYPE)

(2) 有符號資料型別(SIGNED TYPE)

2.4 用戶自定義資料型別方式

(1) TYPE陳述句用法

(2) SUBTYPE陳述句的用法

(3) 列舉型別

(4) 陣列型別




(5) 記錄型別


(6) 資料型別轉換







四、VHDL In Quartus Ⅱ
這章里邊部分參考一位旁友hayroc的筆記,一起放上來方便看,
1、VHDL入門
(1)vhdl設計組成:
庫和程式包(libary, package)
物體(entity)
結構體(architecture)
配置(configuration)
通俗來講:
庫和包 -> 材料,工具箱
物體 -> 硬體外部的介面
結構體 -> 硬體內部的具體實作
(2)語法
物體:
entity 物體名 is
generic(常數名:資料型別:初值)
port(埠信號名:資料型別)
end 物體名
結構體:通過vhdl陳述句描述物體的具體行為和邏輯功能
architecture 結構體名 of 物體名 is
說明部分(可選,如資料型別type 常數constand 信號signal 元件component 程序pocedure 變數variable和行程process等)
begin
功能描述部分
end 結構體名
邏輯
if 條件 then
--do something;
else if 條件 then
--do something;
else
--do something;
end if;
回圈
for x in 0 to n loop
--do something;
end loop;
運算子
賦值運算:
<= 信號賦值
:= 變數賦值
=> 陣列內部分元素賦值
邏輯運算:
not 非
and 與
or 或
nand 與非
nor 或非
xor 異或
注意:對陣列型別,參與運算的陣列位數要相等,運算為對應位進行
算術運算:
+ 加
- 減
* 乘
/ 除
mod 模
rem 取余
** 指數
abs 絕對值
注意:盡量只使用加減
關系運算:
=> 大于等于
<= 小于等于
大于
< 小于
/= 不等于
= 等于
連接運算:
& 連接運算結果為同型別構成的陣列
注意:從本質上講,VHDL代碼是并發執行的,只有PROCESS,FUNCTION或者PROCEDURE內部的代碼才是順序執行的,值得注意的是,盡管這些模塊中的代碼是順序執行的,但是當它們作為一個整體是,與其他模塊之間又是并發的,IF,WAIT,CASE,LOOP陳述句都是順序代碼,用在PROCESS,FUNCTION和PROCEDURE內部,
2、代碼實體
(1)半加器
--halfadder
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity halfadder is
port(a, b : in std_logic;
s, c : out std_logic
--s -> sum, c -> carry
);
end halfadder;
architecture f_halfadder of halfadder is
begin
s <= a xor b;
c <= a and b;
end f_halfadder;
(2)一位全加器
--fulladder
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity fulladder is
port(a, b, c0 : in std_logic;
s, c1 : out std_logic
);
end fulladder;
architecture f_fulladder of fulladder is
begin
s <= a xor b xor c0;
c1 <= (a and b) or (c0 and (a xor b));
end f_fulladder;
(3)四位加法器
--add4
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity add4 is
port(a, b : in std_logic_vector(3 downto 0);
s : out std_logic_vector(3 downto 0);
c0 : in std_logic;
c1 : out std_logic
);
end add4;
architecture f_add4 of add4 is
begin
--模擬手算加法
process(a, b, c0)
variable t : std_logic;
begin
t := c0;
for x in 0 to 3 loop
s(x) <= a(x) xor b(x) xor t;
t := (a(x) and b(x)) or (t and (a(x) xor b(x)));
end loop;
c1 <= t;
end process;
end f_add4;
(4)四位不帶符號乘法器
直接使用 ”+“ 號要結果的存盤要多加一位,
---mul4
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity mul4 is
port(n0, n1 : in std_logic_vector(3 downto 0);
a0 : out std_logic_vector(7 downto 0)
);
end mul4;
architecture f_mul4 of mul4 is
signal t0, t1, t2, t3 : std_logic_vector(3 downto 0);
begin
process(n0, n1, t0, t1, t2, t3)
begin
--模擬手算乘法
if n1(0) = '1' then
t0 <= n0;
else
t0 <= "0000";
end if;
if n1(1) = '1' then
t1 <= n0;
else
t1 <= "0000";
end if;
if n1(2) = '1' then
t2 <= n0;
else
t2 <= "0000";
end if;
if n1(3) = '1' then
t3 <= n0;
else
t3 <= "0000";
end if;
a0 <= ("0000" & t0) + ("000" & t1 & '0') + ("00" & t2 & "00") + ('0' & t3 & "000");
end process;
end f_mul4;
(5)五位帶符號數的補碼陣列乘法器
最后的原理圖,

comp4(四位求補器)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity comp4 is
port (c0 : in std_logic;
flag1: in std_logic;
num1 : in std_logic_vector (3 downto 0);
flag2: in std_logic;
num2 : in std_logic_vector (3 downto 0);
res1 : out std_logic_vector(3 downto 0);
res2 : out std_logic_vector(3 downto 0));
end comp4;
architecture f_comp4 of comp4 is
begin
process(num1,flag1,num2,flag2,c0)
Variable tmp_ci:std_logic;
begin
res1<="0000";
res2<="0000";
tmp_ci:='0';
for i in 0 to 3 loop
res1(i)<=(num1(i) xor (tmp_ci and flag1));
tmp_ci:=num1(i) or tmp_ci;
end loop;
tmp_ci:='0';
for i in 0 to 3 loop
res2(i)<=(num2(i) xor (tmp_ci and flag2));
tmp_ci:=num2(i) or tmp_ci;
end loop;
end process;
end f_comp4;
mult_array(四位乘法陣列)
--這里實作的是沒有符號的乘法陣列
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity mult_array is
port(num1, num2: in std_logic_vector(3 downto 0); -- num1是被乘數,舗um2是成乘數
res : out std_logic_vector(7 downto 0);
test: out std_logic_vector(7 downto 0));
end mult_array;
architecture f_mult_array of mult_array is
TYPE mult_array is Array(3 downto 0) of std_logic_vector(6 downto 0);
Signal m: mult_array;
begin
process(m,num1,num2)
Variable tmp_num2:std_logic_vector(3 downto 0);
begin
for i in 0 to 3 loop
m(i)<="0000000";
if num2(i)='1' then
m(i)(3+i downto i)<=num1(3 downto 0);
end if;
end loop;
--test(7 downto 4 ) <= num2(3 downto 0);
res<=('0' & m(0)) + ('0' & m(1)) + ('0' & m(2)) + ('0' & m(3));
end process;
end f_mult_array;
comp8(八位求補器)
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity comp8 is
port (e, c0 : in std_logic;
num : in std_logic_vector (7 downto 0);
result : out std_logic_vector(7 downto 0));
end comp8;
architecture f_comp8 of comp8 is
begin
process(num,e,c0)
Variable tmp_ci:std_logic;
begin
tmp_ci:='0';
for i in 0 to 7 loop
result(i)<=(num(i) xor (tmp_ci and e));
tmp_ci:=num(i) or tmp_ci;
end loop;
end process;
end f_comp8;
3、Debug日志
1、同一個專案檔案有兩個vhd檔案時,如果要對不同的vhd檔案進行仿真的話需要對先把要仿真的檔案置于top entity,然后把這個檔案編譯一遍,這樣才能在node finder里邊找到對應的引腳,
2、信號的賦值操作只有在行程結束后才會進行,所以如果信號在行程內被多次賦值的話,只有最后一次賦值操作才會起作用,所以在行程內寫演算法一般都是用variable,signal和variable的區別具體可以看這篇blog => VHDL中信號與變數的區別及賦值的討論
3、當自己制作的組件的某一個介面是一個陣列,這時候要用總線連接,具體的連法可以看這篇blogquartus總線怎樣連接
4、在用vhdl寫組件的的時候,在定義process的時候,一定要把用到的input的埠寫進porcess定義時的括號里邊,否則可能導致的后果就是你把你寫好的這個組件生成出來之后,結果永遠對不上!
錯誤請指出,不定時更新,ths!
May you give me a like?
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/277365.html
標籤:其他
上一篇:Android 計時器,定時功能
