有寫過 C 語言的人, 都知道, 主程式就是 main(); 而, 程式主體就是左右大括號 {} 包起來.
不論是什麼語法, 都一樣. Verilog也不例外.
只是, 在 Verilog or VHDL 沒有什麼 main 這種規定.
可以取任意名字, 這個是跟 C 有大大大不同的地方.
而~~~為什麼我在這裡要拿 C 跟 Verilog 來比呢?
其實, 這兩種語法用途完全不同, 拿來比是不適當的. 但是, 它們卻在語法上有相似的地方.
我自己不是一個正統的 ASIC 科班出身的工程師, 我一路走來, 從 assembly 到 C 到 VHDL 再到 Verilog.
說真的, VHDL 我學了老半天, 實在是~~我學得~~~有些笨手笨腳的, 最後終究轉戰 Verilog 了. 原因無它, 就是它們對我而言超像的.
扯遠了, 回歸主題~~~
而, 在 Verilog 的世界裡, 都是模組(module) 的模式在進行的.
每個模組(module) 也有像 C 一樣用{}來把程式主體包起來的
但是, 是不同的表示方式.
module 等同於 C 的 {
endmodule 等同於 C 的 }
所以, 要寫一個叫 adder 的 module
module adder ();
endmodule
這樣就好了~~~但是, 一個 module 沒有輸出入, 那不就白搭了嗎?
那我們就來設計一個 {Carry_Out , Sum = A_In + B_In + Carry_In} 的 module
module adder (A_In, B_In, Carry_In, Sum, Carry_Out);
input A_In, B_In, Carry_In;
output Sum, Carry_Out;
endmodule
還有另一程寫法
module adder (input A_In,
input B_In,
input Carry_In,
output Sum,
output Carry_Out
);
endmodule
那....哪個方式比較好呢? 就大家習慣不同~~~其實個人認為都可以的啦~~~
再來, 怎麼實現呢?
其實, 在 ASIC or FPGA 的世界裡, 常常會有人在提 combination design 跟 synchronize design
就差在, 有沒有 clock 來做同步
我們就先來個 combination design 吧
module adder (A_In, B_In, Carry_In, Sum, Carry_Out);
input A_In, B_In, Carry_In;
output Sum, Carry_Out;
wire Sum, Carry_Out;
assign Sum = ({A_In,B_In,Carry_In} == 3'b000 ) ? 1'b0 :
({A_In,B_In,Carry_In} == 3'b001 ) ? 1'b1 :
({A_In,B_In,Carry_In} == 3'b010 ) ? 1'b1 :
({A_In,B_In,Carry_In} == 3'b011 ) ? 1'b0 :
({A_In,B_In,Carry_In} == 3'b100 ) ? 1'b1 :
({A_In,B_In,Carry_In} == 3'b101 ) ? 1'b0 :
({A_In,B_In,Carry_In} == 3'b110 ) ? 1'b0 : 1'b1;
assign Carry_Out = ({A_In,B_In,Carry_In} == 3'b000 ) ? 1'b0 :
({A_In,B_In,Carry_In} == 3'b001 ) ? 1'b0 :
({A_In,B_In,Carry_In} == 3'b010 ) ? 1'b0 :
({A_In,B_In,Carry_In} == 3'b011 ) ? 1'b1 :
({A_In,B_In,Carry_In} == 3'b100 ) ? 1'b0 :
({A_In,B_In,Carry_In} == 3'b101 ) ? 1'b1 :
({A_In,B_In,Carry_In} == 3'b110 ) ? 1'b1 : 1'b1;
endmodule
再來個 synchronize design
再先再加入一個輸入, 就是 clock 囉!!
module adder (clock, A_In, B_In, Carry_In, Sum, Carry_Out);
input clock, A_In, B_In, Carry_In;
output Sum, Carry_Out;
reg Sum, Carry_Out;
always @(posedge clcok)
begin
case({A_In,B_In,Carry_In})
3'b000: begin Sum <= 1'b0; Carry_Out <= 1'b0; end
3'b001: begin Sum <= 1'b1; Carry_Out <= 1'b0; end
3'b010: begin Sum <= 1'b1; Carry_Out <= 1'b0; end
3'b011: begin Sum <= 1'b0; Carry_Out <= 1'b1; end
3'b100: begin Sum <= 1'b1; Carry_Out <= 1'b0; end
3'b101: begin Sum <= 1'b0; Carry_Out <= 1'b1; end
3'b110: begin Sum <= 1'b0; Carry_Out <= 1'b1; end
3'b111: begin Sum <= 1'b1; Carry_Out <= 1'b1; end
endcase
endmodule
當然, 要實現一個加法器, 有很多方式, 這不是唯一或唯二的寫法.
寫程式, 就每個人 coding 習慣不同而有所不同, 大家自己揣摩~~~