加入星計劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請入駐 產(chǎn)業(yè)圖譜

從電路到verilog | 編程綜合運(yùn)用,不得不從DDS的實例說起

2016/08/30
14
  • 1評論
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論

?

實際上說道上一講,老衲就可以體面撤退了。該說的都說了,細(xì)枝末節(jié)嘛,也不適合講座這種短篇幅的東西來表現(xiàn)。可是老僧舍不得大家?。▽嶋H上是舍不得出場費(fèi)),所以湊個整兩個九講。話說回來,“九”這個數(shù)字一向與武林有關(guān):《九陰真經(jīng)》、《九陽真經(jīng)》還有降龍 2×9 掌……


這一講呢,將會綜合應(yīng)用前面的全部知識,來完成一個相對較大的系統(tǒng)。希望施主們打起七十二分的精神,如果哪些知識點忘掉了,也需要往回翻一翻、看一看。


再嘮叨一句:講座篇幅短短幾十頁,不可能包含 Verilog 語言全部的內(nèi)容,就是與電路有關(guān)的也不全。想想看,IEEE 標(biāo)準(zhǔn) 200 多頁,除了 DPI 也有 150 頁的樣子,這個講座才幾頁啊。喜歡老衲啰嗦的老少爺們也不要失望,老和尚“慈悲為懷,善念為本”早就寫得了《Verilog 傳奇》的手抄本小冊子。您老聽著高興,可以到茶房那里購買,“走過,路過,可別錯過啊”。


好了,閑言少敘,書歸正傳?,F(xiàn)在老僧開始給大伙兒講講 DDS。


1. 概念算法,兩不耽誤
按照一般論文緒論里面吹牛的定義:直接數(shù)字合成是一種數(shù)字電子方式,它從一個單一(或混合)的時鐘源中產(chǎn)生任意波形和頻率。與傳統(tǒng)的頻率合成器相比,DDS 具有低成本、低功耗、高分辨率和快速轉(zhuǎn)換時間等優(yōu)點,廣泛使用在電信與電子儀器領(lǐng)域,是實現(xiàn)設(shè)備全數(shù)字化的一個關(guān)鍵技術(shù)。


DDS 的一般結(jié)構(gòu)如圖 1 所示,其數(shù)字邏輯部分包括控制模塊、累加器和正弦函數(shù)發(fā)生器三個部分??刂颇K可以串行或并行的方式裝載并寄存用戶輸入的頻率控制碼;而累加器根據(jù)頻率控制碼在每個時鐘周期內(nèi)進(jìn)行相位累加,得到一個相位值;正弦函數(shù)發(fā)生器則對該相位值計算數(shù)字化正弦波幅度。DDS 芯片輸出的一般是數(shù)字化的正弦波,因此還需經(jīng)過高速 D/A 轉(zhuǎn)換器低通濾波器才能得到一個可用的模擬頻率信號。

圖 1 DDS 系統(tǒng)整體結(jié)構(gòu)


要使 DDS 系統(tǒng)工作需要兩個操作階段:我們稱之為編程和運(yùn)行。


在編程這一階段里,電子控制器把數(shù)據(jù)載入至存儲器中。數(shù)據(jù)的每一個單元是一個用來表示當(dāng)前時刻信號幅度的二進(jìn)制數(shù)。存儲器中這些數(shù)據(jù)的排列(數(shù)組)構(gòu)成一張振幅表,表示每一時刻當(dāng)前波形的振幅。舉個例子,在一張振幅表中,前一半的數(shù)全為 0,后一半全為波形振幅的最大值(100%),這些數(shù)據(jù)就表示“方波”了。任何波形都可以通過簡單地改變這些數(shù)據(jù)來產(chǎn)生。


在運(yùn)行這一階段中,累加器受系統(tǒng)時鐘參考源的控制,每一個脈沖自增。相位累加器的輸出(相位)通常就是數(shù)組中依次輸出的各個數(shù)據(jù)。最后會被 DAC 依次轉(zhuǎn)換成模擬波形。
先看控制模塊,這個主要負(fù)責(zé)數(shù)字 DDS 的輸入輸出接口。例如,信號頻率的輸入可以通過串口線,由上位機(jī)輸入;當(dāng)然,也可以通過按鍵在 PCB 板上完成。對于的 ADC 接口,則與選擇的具體器件有關(guān)。可能還需要顯示一下頻率數(shù)值,這個就和 BCD(Binary-Coded Decimal?,BCD)譯碼器及其接口,乃至液晶顯示( Liquid Crystal Display, LCD)接口有關(guān)聯(lián)了。這部分很重要,但是不是本講的重點,且容貧道一嘴帶過。


累加器部分,更加簡單的,就是一個允許設(shè)置累加步長的累加器了。更加復(fù)雜一點的結(jié)構(gòu)是還允許設(shè)置初始值,也就是所謂初始相位。實際工程中,初始相位的設(shè)置意義不大,就不寫入代碼了。

?


現(xiàn)在講到關(guān)鍵點正弦函數(shù)發(fā)生器了。一般而言,九成九的正弦函數(shù)發(fā)生器會采用 ROM 的形式。輸入的地址對應(yīng)規(guī)格化的角度值,輸出的數(shù)據(jù)則對應(yīng)該角度的正弦值。問題的核心是:到底存儲多少數(shù)據(jù)。0 度到最接近 360 度的一個分度,自然是一個選擇,但是這樣實際上浪費(fèi)了大量的存儲空間。


顛來倒去一句話:有 0 度到 90 度的正弦值,就可以得到全部是個象限的正弦值。如圖 2,其中給出了不同象限的正弦值的計算公式以及其他設(shè)計中需要的內(nèi)容。圖中的公式就是所謂周期性的公式了,用于非第一象限的正弦值的計算。另外為了方便,給出了一些特殊角度的地址,以及各個象限的地址開頭兩比特值和正弦值的符號信息。


圖 2 四個象限的正弦函數(shù)


為了實現(xiàn)用 0 到 90 度的正弦函數(shù)值,計算 0 到 360 的正弦值的目的,需要將圖 9.1 里面的正弦函數(shù)發(fā)生器劈為四份,如圖 9.3 所示。第一部分是 0 到 90 度的正弦函數(shù)發(fā)生器,這個無需多說。第二個是地址轉(zhuǎn)換模塊,它去掉原來 0 到 360 度對應(yīng)的“長地址”的最高兩個比特(90 度例外,只去掉最高一個比特),這樣得到 0 到 90 度對應(yīng)的“短地址”。第三部分叫符號產(chǎn)生模塊,負(fù)責(zé)根據(jù)當(dāng)前角度對應(yīng)的象限計算正弦值的符號。注意圖 9.2 的地址與符號部分,正弦值的符號實際上就是對應(yīng)地址的最高位。由于 0 到 90 度的正弦函數(shù)發(fā)生器可能計算時候有時延,所以符號產(chǎn)生模塊還負(fù)責(zé)這個時延的矯正。最后一個模塊是正弦值處理模塊,就是正數(shù)值透傳、負(fù)數(shù)值變?yōu)?a class="article-link" target="_blank" href="/baike/1572789.html">補(bǔ)碼的功能。


圖 3 正弦函數(shù)發(fā)生器(0 到 360 度)結(jié)構(gòu)


地址轉(zhuǎn)換與符號產(chǎn)生模塊和正弦值處理模塊的代碼也無需詳述。
把系統(tǒng)結(jié)構(gòu)中除了 0 到 90 度的正弦函數(shù)發(fā)生器的各個部分打包,叫做 DDS 框架,其架構(gòu)與代碼如圖 4 所示。


圖 4 DDS 框架與其他部分的關(guān)系

?


2. 非線數(shù)值,折線逼近
有道是“一將名成萬古枯”,在數(shù)字邏輯設(shè)計領(lǐng)域雖然沒有那么慘烈,卻也是“領(lǐng)導(dǎo)動動嘴。地下跑斷腿”。就拿前面提到的“用直線 / 折線擬合正弦函數(shù)的”這個思想為例,提出想法的人可以簡單地就是如圖 5 的勾上幾筆,看似就圓滿了。


但是接下來的工作還有很多:幾段折線合適?這些折線的位置如何確定?系數(shù)如何計算?接著還有定點化如何完成?最后有數(shù)字邏輯系統(tǒng)的結(jié)構(gòu)與實現(xiàn)細(xì)節(jié)。這些老大可以不考慮,工程師卻不能不研究。


圖 5 折線法計算正余弦值的示意圖


按照橫軸 / 角度均勻選擇線段的起始點顯然是一個最簡單的方法,但是這絕對不是一個好的方法。理由很簡單,正弦曲線的曲率 -- 或者叫導(dǎo)數(shù) -- 變化時不均勻的。均勻選擇線段會造成曲率大的地方,計算誤差大;而曲率小的地方,計算誤差也小。這顯然是不合理的。


具體算法呢,超出了這套書的范圍(欲知詳情,請看小冊子),按下不表。反正施主們得到了下面的數(shù)值:


以橫軸采樣個數(shù) 64 個以及最大允許誤差 0.02 作為輸入,可以得到一個正弦函數(shù)的 14 段折線擬合,有關(guān)信息見表 1。


表 1 折線擬合正弦函數(shù)中,線段信息

折線標(biāo)號

起點(度)

系數(shù)

折線標(biāo)號

起點(度)

系數(shù)

a

b

a

b

0

0

0.9996

0

7

21.4286

0.9260

0.0188

1

4.2857

0.9971

0.0001

8

25.7143

0.8953

0.0318

2

7.1429

0.9921

0.0006

9

30.0000

0.8529

0.0529

3

10.0000

0.9847

0.0017

10

35.7143

0.7478

0.1158

4

12.8571

0.9748

0.0037

11

50.0000

0.5405

0.2916

5

15.7143

0.9625

0.0068

12

67.1429

0.2577

0.6160

6

18.5714

0.9478

0.0112

13

85.7143

0.0498

0.9217


對于每段折線都有:
?
其中,x 為弧度值。例如,對于 5 度(弧度 0.0873)的角度值,其正弦函數(shù)值為 sin(0.0873) ≈ 0.0887;此時 x 位于第二段折線的范圍里面,按照折線計算 y = 0.9921 × 0.0873 + 0.0006 ≈ 0.0872;誤差大約為 0.001,這已經(jīng)算是很精確了。通過程序掃描,這個算法最大的誤差為 0.019。


然后是定點化,忘記如何做的請回去復(fù)習(xí)則個。


考察折線法有關(guān)的數(shù)值的取值范圍,定義其定點化格式如表 2,其中“value_width”是待輸出的結(jié)果的位寬。需要注意的是 a_f 由于其取值范圍的特殊,設(shè)計中比其他有關(guān)數(shù)值多了一個比特。


表 2 折線法有關(guān)的數(shù)值的取值范圍與定點化格式

?

折線起始點 / 地址

a_f

b

結(jié)果

取值范圍

[0, 2π]

[0, 2π]

[0, 1]

[0, 1]

定點化格式

Q(address_width+1).0

Q(value_width+1).(value_address)

Q(value_width).(value_address)

Q(value_width).(value_address)


對應(yīng)定點化計算的公式為:


其中,A_f 和 B_f 是定點化后的折線的系數(shù)。


此時,y 有(value_width + address_width +1 )個比特的位寬,而要求結(jié)果只有 value_width 個比特的位寬,需要進(jìn)行截位處理。根據(jù)已知條件,這個截位也有些特殊。計算結(jié)果 y 的最高比特一定為零,這個是公式的含義告訴我們的(提示一下:正弦值)。因此上系統(tǒng)輸出的結(jié)果應(yīng)該是 y 從第二個最高比特開始的 value_width 個比特。
以 address_width = 6 和 value_width = 7 為例,可以獲得折線的信息如表 3 所示。


表 3 折線擬合正弦函數(shù)中,線段定點化信息(十六進(jìn)制表示)

折線標(biāo)號

起點的短地址

系數(shù)

折線標(biāo)號

起點的短地址

系數(shù)

A_f

B_f

A_f

B_f

0

00

c8???

00?????????

7

0f

b9

03

1

03

c7

01

8

12

b3

05

2

05

c6

01

9

15

ab

07

3

07

c5

01

10

19

96

0f

4

09

c3

01

11

23

6c

26

5

0b

c1

01

12

2f

34

4f

6

0d

be

02

13

3c

0a

76


另外可以得到:相對浮點運(yùn)算,定點運(yùn)算又帶來了 0.011 的計算誤差。


至此,定點化結(jié)束,可以交給數(shù)字邏輯設(shè)計的有關(guān)人員,開始具體實現(xiàn)方面的工作了。
具體的設(shè)計思路倒也不難:是“先選系數(shù)后計算”,也就是先判斷所在折線序號,得到對應(yīng)系數(shù)再計算,其基本結(jié)構(gòu)見圖 6 所示;值得一提的是,只需要這些折線的終點或者起點里面的一個信息就足夠了,因為折線是首尾相連的。這里老衲采用了終點。還有一個小技巧是,最后一個折線的終點也是多余的,因為它必然對應(yīng)最高的地址。


圖 6 “先選系數(shù)后計算”結(jié)構(gòu)


多路選擇模塊稍稍復(fù)雜一點點,這里捎帶腳介紹一下。如圖 7 所示,多路選擇模塊由若干比較器和一個用“case”書寫的選擇器組成。比較器中 points 為各段折線對應(yīng)的重點。選擇器這有一種特殊的編碼決定選擇哪一個信號,具體編碼大伙兒自己分析。


圖 7 多路選擇模塊的結(jié)構(gòu)


在實現(xiàn)細(xì)節(jié)上還有一個很多人會跌掉的坑,那就是關(guān)于 90 度的處理。搞不好,就會在 90 度的時候,計算出 0 度的正弦值。這樣輸出的曲線就會出現(xiàn)在應(yīng)該最大值 1 的時候,輸出一個深坑(0 值)的情況。對于這種情況,可以特殊問題特殊處理,直接賦值 90 度的正弦值。在本回書的例子里面,采用了一個迂回的方式,設(shè) 90 度為最接近它的最大角度(例如,步長為 1 度的時候,輸入的“短地址”為 90 度,計算時候的地址則取為 89 度),在假設(shè)系統(tǒng) 8 比特輸出位寬的前提下,不會產(chǎn)生輸出誤差的。

?


在例 1 中給出了折線法計算 0 度到 90 度正弦值的代碼,結(jié)合前面介紹過的 DDS 的框架,就可以得到完整的 DDS 系統(tǒng)了。


【例 1】折線法計算 0 度到 90 度正弦值的代碼
module line_sin_0_90
#(parameter ADDRESS_WIDTH = 8,
//Bit width for phase counter and step
parameter VALUE_WIDTH = 8
//Output value's bit width
)
? (
??? input CLK,
??? input RESET,
??? input[ADDRESS_WIDTH - 1 - 1: 0] address,
??? output reg[VALUE_WIDTH - 1 - 1 : 0] value
? );

//Definition for Variables in the module
integer loop;
//Loop variable

reg[ADDRESS_WIDTH - 1 - 2: 0] intra_address;
//Intra address for calculation
//Change 90 degree to 111....111
//Cut the MSB
reg[ADDRESS_WIDTH - 1 - 2: 0] intra_address_delay;
//Delay for coefficients selection

reg[VALUE_WIDTH - 1 : 0] ceo_a;
//Fixed point 1.VALUE_WIDTH
reg[VALUE_WIDTH - 2 : 0] ceo_b;
//Fixed point 0.VALUE_WIDTH
//coefficients for the lines

wire[VALUE_WIDTH - 1 + 1 + ADDRESS_WIDTH - 2 - 1: 0] long_value;
//Long function value without truncation
//Length: a * address
wire[VALUE_WIDTH:0] short_value;
//Truncation value

//definition JUDGEMENTS and Coefficients Constant
//Application part: Insert DEFINITION OF JUDGEMENTS and Coefficients Constant(DO NOT REMOVE!)
//Below code/s was/were generated by the application
reg [12 : 0] judgments;
wire [7 : 0] a[13 : 0];
wire [6 : 0] b[13 : 0];
wire [5 : 0] points[12 : 0];
//Above code/s was/were generated by the application

//Logical
//Constant Tables
//Application part: Insert Constant Tables (DO NOT REMOVE!)
//Below code/s was/were generated by the application
//coefficients a and b
assign a[0] = 8'b11001000;
assign b[0] = 7'b0000000;
assign a[1] = 8'b11000111;
……
assign a[13] = 8'b00001010;
assign b[13] = 7'b1110110;

//Connect points between lines
assign points[0] = 6'b000011;
……
assign points[12] = 6'b111100;
//Above code/s was/were generated by the application

//Value calculation on the line
assign long_value = ceo_a * intra_address_delay;
assign short_value =
??????? long_value[VALUE_WIDTH - 1 + 1 + ADDRESS_WIDTH - 2 - 1 : ADDRESS_WIDTH - 2]
?????????? + {1'b0, ceo_b};

always @ (posedge CLK or negedge RESET)
//Address adjust: 90 degree operation
begin
??? if (!RESET)
??? //Reset enable
??? begin
??????? intra_address <= {(ADDRESS_WIDTH - 1){1'b0}};
??? end
??? else
??? begin
??????? if (address[ADDRESS_WIDTH - 1 -1])
??????? //90 degree
??????? begin
??????????? intra_address <= {(ADDRESS_WIDTH - 2){1'b1}};
??????????? //To 111...111
??????? end
??????? else
??????? begin
??????????? intra_address <= address[ADDRESS_WIDTH - 1 - 2: 0];
??????????? //Keep original value???????
??????? end
??? end
end

always @ (posedge CLK or negedge RESET)
//Address delay: waiting for coefficients selection
begin
??? if (!RESET)
??? //Reset enable
??? begin
??????? intra_address_delay <= {(ADDRESS_WIDTH - 1){1'b0}};
??? end
??? else
??? begin
??????? intra_address_delay <= intra_address;
??? end
end

always @ (posedge CLK or negedge RESET)
//coefficients selection
begin
??? if (!RESET)
??? //Reset enable
??? begin
??????? ceo_a <= {(VALUE_WIDTH + 1){1'b0}};
??????? ceo_b <= {(VALUE_WIDTH ){1'b0}};
??? end
??? else
??? begin
??????? case(judgments)
//Application part: Insert Coefficient Selection codes (DO NOT REMOVE!)????????
//Below code/s was/were generated by the application
???????? 13'b1111111111111:
???????? begin
???????????? ceo_a <= a[0];
???????????? ceo_b <= b[0];
???????? end

???????? 13'b1111111111110:
???????? begin
???????????? ceo_a <= a[1];
???????????? ceo_b <= b[1];
???????? end

???????? ……

???????? 13'b0000000000000:
???????? begin
???????????? ceo_a <= a[13];
???????????? ceo_b <= b[13];
???????? end

//Above code/s was/were generated by the application
????????
???????? default:
???????? begin
??????????? ceo_a <= {(VALUE_WIDTH + 1){1'b0}};
?????????????? ceo_b <= {(VALUE_WIDTH ){1'b0}};
???????? end
??????? endcase
??? end
end

always @ (posedge CLK or negedge RESET)
//Function value output
begin
??? if (!RESET)
??? //Reset enable
??? begin
??????? value <= {(VALUE_WIDTH - 1){1'b0}};
??? end
??? else
??? begin
??????? value <= short_value[VALUE_WIDTH - 1 : 0];
??????? //Truncation: MSB and tails
??? end
end

//Judgment for which line here is
always @(*)
begin
//Application part: Insert Comparisons (DO NOT REMOVE!)
//Below code/s was/were generated by the application
??? for (loop = 0; loop < 13; loop = loop + 1)
??? begin
??????? judgments[loop] <= (intra_address < points[loop]);
??? end
//Above code/s was/were generated by the application
end

endmodule

?

3. 系統(tǒng)驗證,中規(guī)中矩
這個系統(tǒng)包含很多模塊,其他模塊好說,進(jìn)行仿真驗證的時候,肉眼都可以看出它到底合適不。就是 0 到 90 度的正弦函數(shù)發(fā)生器相對輸出復(fù)雜,例如對于 7 比特輸入就有 65 個輸出信號需要對比。對于這樣的模塊,最好的驗證方法是測試向量方法。這個方法以前提到過,直接上代碼如例 2。


【例 2】0 到 90 度的正弦函數(shù)發(fā)生器驗證代碼
`timescale 10 ns/100 ps
//Simulation time assignment

//Insert the modules

module sin_0_90_test;
//definition for Variables
reg clk;
reg reset;

reg[7:0] cntr;

wire[6:0] result;

reg[6:0] test_vector_monory[64:0];
wire[6:0] test_vector;
//Test Vector Value

wire[7:0] addr;
//Address of test vectors

wire right;
//Results right?

//Connection to the modules
ROM_sin_0_90 LS (.CLK(clk), .RESET(reset), .address(cntr[6:0]),
????????????????? .value(result));

assign test_vector = test_vector_monory[addr];
assign right = (test_vector == result);
assign addr = (cntr >= 3) ? ( cntr - 3): ( 64 - 3 +? cntr);
//Delay for operation

//Clock generation
……

//Reset operation
……

//Load the test vectors
??? initial?
??? begin
????? $readmemh("sin2line_test_vector_2016_3_13_17_3_10.txt",
????????????????? test_vector_monory);
??? end
???????
//Couner as input
??? ……

endmodule


代碼中,“test_vector_monory”里面存儲了其他程序產(chǎn)生的對應(yīng)正弦值,“addr”是對于實際處理模塊帶來的時延的修正。如果“right”信號一直是高電平,則說明 0 到 90 度的正弦函數(shù)發(fā)生器功能正確。


到了最后的系統(tǒng)驗證的階段了,當(dāng)然也可以采用上面的測試向量的方法完成。書不重敘,這里再教施主們一個輸出信號進(jìn)行性能驗證的手段。這個手法也在前面一章里面介紹過,莫過于寫文件罷了。但是具體到正弦函數(shù)的性能驗證,卻還是有些技巧的。
對于正弦函數(shù)性能的測試,大多數(shù)人一定會想到快速傅里葉變換(Fast Fourier Transform,F(xiàn)FT)。信號頻譜的最高峰就是正弦信號的線譜,其平方為正弦信號的能量;其他部分就是系統(tǒng)產(chǎn)生的噪聲,噪聲能量為其能量值和。這樣就可以得到系統(tǒng)最重要的性能:信噪比 (信號噪聲比,Signal-to-noise ratio ,SNR)。但是實際中,F(xiàn)FT 也是優(yōu)缺點的。這就是對于非整周期采樣的數(shù)據(jù),會有頻譜散射效應(yīng)。有興趣的人士可以用任何具備 FFT 功能的工具做一個有趣的實驗。分別產(chǎn)生兩個序列:第一個序列為 0 度到 359 度的正弦值,第二個序列為 0 度到 358 度的正弦值。分別對于這兩個序列做 FFT 并且畫出幅度值,兩者的區(qū)別立現(xiàn)。


針對這個情況,在采集 DDS 系統(tǒng)的輸出的時候,不能任意采集。采集的樣本必須滿足“滿周期”的性質(zhì)。細(xì)心的觀眾一定主要到了,在 DDS 的框架里面有一個叫“zero_address”的信號。這個信號當(dāng)長地址為全零的時候為高電平。換句話說,該信號兩次為高之間的信號為滿周期的信號。


現(xiàn)在沒什么能夠攔阻人類進(jìn)入 DDS 時代的腳步了,前進(jìn)!圖 8 是本講介紹的 DDS 的輸出,其中還表現(xiàn)了一次頻率變化的過程。


圖 8 DDS 的輸出信號


至于輸出三角波、鋸齒波或者方波的 DDS,相對于上面的系統(tǒng),基本不值一提,就不多說了。


最后再說一下,限于篇幅不好詳細(xì)展開,有求知欲聽眾千萬要買小冊子??!


這正是:

語言本來無情物,上天入地多用途。一般時鐘做輸入,產(chǎn)生正弦片外吐。
外圍框架無特殊,函數(shù)產(chǎn)生玄妙出。驗證方法有用處,整周采樣成數(shù)組。

與非網(wǎng)原創(chuàng)內(nèi)容,謝絕轉(zhuǎn)載!

系列匯總:

之一:溫故而知新:從電路里來,到 Verilog 里去!

之二:Verilog 編程無法一蹴而就,語言層次講究“名正則言順”

之三:數(shù)字邏輯不容小窺,電路門一統(tǒng)江湖

之四:Verilog 語言:還真的是人格分裂的語言

之五:Verilog 不難學(xué),聊聊時序邏輯那些事兒

之六:數(shù)字電路設(shè)計:有理論、有電路、有代碼“三位一體”

之七:熟讀語言要素,不會編程也懂 verilog

之八:IP 設(shè)計可企及,宏和參數(shù)只是為了合并同類模塊

之九:欲要系統(tǒng)能跑起,仿真驗證是真諦

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

本名:吳濤,通信專業(yè)博士,畢業(yè)后十多年從事無線通訊產(chǎn)品的研發(fā)工作。了解W-CDMA、TDS-CDMA和LTE的標(biāo)準(zhǔn)協(xié)議、接收機(jī)算法以及系統(tǒng)架構(gòu)和開發(fā)。從事過關(guān)于W-CDMA的FPGA IP core設(shè)計工作,也完成過W-CDMA和TDS-CDMA的接收機(jī)理論研究和鏈路仿真工作。綜合上面的工作,最終選擇了無線通訊的系統(tǒng)設(shè)計和標(biāo)準(zhǔn)設(shè)計工作。目前擁有100多個已授權(quán)的發(fā)明專利,是某通訊行業(yè)標(biāo)準(zhǔn)文件的第一作者,亦有專利思想被寫入3GPP協(xié)議。已出版FPGA設(shè)計專業(yè)著作《IP核芯志-數(shù)字邏輯設(shè)計思想》和《Verilog傳奇-從電路出發(fā)的HDL代碼設(shè)計》。