【計算機組成原理 數字邏輯 Verilog】32位加法器的實現:支持整數的加減運算

目錄

  • 0 前言
    • 0.1 使用環境
    • 0.2 知識點
    • 0.3 注意事項
  • 1 建模:1位加法器
    • 1.1 構建基礎模型
      • 1.1.1 一位加法器
        • 1.1.1.1 科技黑箱:外部端口與功能
        • 1.1.1.2 揭秘黑箱:內部結構與模塊
      • 1.1.2 從頂層模塊提取低層模塊:取反功能選擇器
        • 1.1.2.1 科技黑箱:外部端口與功能
        • 1.1.2.2 揭秘黑箱:內部結構與模塊
      • 1.1.3 從頂層模塊提取低層模塊:基礎加法器
        • 1.1.3.1 科技黑箱:外部端口與功能
        • 1.1.3.2 揭秘黑箱:內部結構與模塊
    • 1.2 層次建模
      • 1.2.1 32位加法器
      • 1.2.2 1位加法器
  • 2 實現:1位加法器
    • 2.1 取反選擇器
      • 2.1.1 設計塊
      • 2.1.2 激勵塊
      • 2.1.3 功能驗證
    • 2.2 基礎加法器
      • 2.2.1 設計塊
      • 2.2.2 激勵塊
      • 2.2.3 功能驗證
    • 2.3 1位加法器的實現
      • 2.3.1 設計塊
      • 2.3.2 激勵塊&功能驗證
  • 3 原理講解:實現整數減法,將負數轉換為補碼
    • 3.1 計算機進制數與人類進制數的差別
      • 3.1.1 十進制數轉換為補碼的原理
    • 3.2 進位輸入信號carry_in的作用
  • 3 建模:32位加法器
    • 3.1 科技黑箱:外部端口
    • 3.2 揭秘黑箱:內部細節
      • 3.2.1 組合式設計的核心原則
  • 4 實現:32位加法器
    • 4.1 設計塊
    • 4.2 激勵塊
      • 4.2.1 報錯解決方案
    • 4.3 仿真驗證
  • 5 行為級建模的魅力
    • 5.1 設計塊
    • 5.2 激勵塊
    • 5.3 結果驗證
    • 5.4 思考點
  • 6 由行為級描述掌握幾大重要思想
  • 7 待求解決方案的錯誤

0 前言

0.1 使用環境

  • EDA工具:Vivado 2017.4
  • 硬件描述語言:Verilog HDL

0.2 知識點

  • 加法器(全加器)
  • 多路選擇器
  • Verilog 語言及其設計思想
  • 補碼

0.3 注意事項

本文中所有的Verilog實現部分,均完成了仿真測試,并未進行時序驗證以及后續的邏輯綜合步驟,后續步驟可能會出現問題,請讀者自行完成修改。

1 建模:1位加法器

我們先來構建1位加法器,要知道,32位加法器只不過是將32個1位加法器以特定的方式連接起來,真正的核心是1位加法器的設計

1.1 構建基礎模型

1.1.1 一位加法器

1.1.1.1 科技黑箱:外部端口與功能

功能:能夠實現整數的加減法,這也就意味著

  1. 支持正數和負數,支持加法和減法(事實上,a+(-b) = a - b;負數與減法某種程度上來說,是一樣的)
  2. 能夠識別正負數,并且能夠做出不同的選擇
    1. 遇到正數、加法,直接運算
    2. 遇到負數、減法 ,轉換為補碼再運算

加法器

  • 輸入端口
    • 數據:a,b
    • 進位:carry_in
    • 取反控制:a_invert,b_invert
  • 輸出端口
    • 和:sum
    • 進位:carry_out

特別注意:對于多個加法器組合的情況,carry_in是來自上一個加法器的carry_out,如果位置是第一個,則要置為0

1.1.1.2 揭秘黑箱:內部結構與模塊

一位加法器內部
內部線網:不與外部相連的內部線,就是內部線網,在Verilog設計中需要單獨加上!

1.1.2 從頂層模塊提取低層模塊:取反功能選擇器

1.1.2.1 科技黑箱:外部端口與功能

下圖圖示部分為取反功能選擇器,其功能是控制輸入的數據是否執行取反操作
取反功能選擇器
以下是其外部端口:
取反選擇器

1.1.2.2 揭秘黑箱:內部結構與模塊

取反選擇器內部

多路選擇器的全面講解參考我的另一篇文章:全面剖析數據選擇器

1.1.3 從頂層模塊提取低層模塊:基礎加法器

1.1.3.1 科技黑箱:外部端口與功能

基礎加法器

1.1.3.2 揭秘黑箱:內部結構與模塊

使用數據流建模,兩個邏輯表達式就可以,這個部分是數字邏輯必備知識,不再贅述。

1.2 層次建模

1.2.1 32位加法器

32位加法器
1位加法器1
2
.....
30
31

1.2.2 1位加法器

1位加法器
取反選擇器1
非門
二選一選擇器
取反選擇器2
基礎加法器
與門
或門

2 實現:1位加法器

2.1 取反選擇器

在這里插入圖片描述

2.1.1 設計塊

`timescale 1ns / 1ps// 取反選擇器的設計
module date_invert_choose (input a,            // 數據輸入input a_invert,     // 使能端         output a_out        // 數據輸出);choose_2to1 CH0 (a,~a,a_invert,a_out);  // 調用二選一選擇器實例endmodule// 二選一選擇器
module choose_2to1 (input d0,d1,    // 數據輸入input add,      // 地址控制output out      // 數據輸出);assign out = (~add)&d0 | add&d1;endmodule

FPGA優化結果如下:
FPGA

2.1.2 激勵塊

設置激勵塊有兩個口訣:

  • 調用模塊,建實例
  • 設置輸入,驗輸出
`timescale 1ns / 1psmodule test;// 設置變量reg a;          // 數據輸入reg a_invert;   // 控制輸入wire a_out;     // 數據輸出       // 調用實例【調用模塊建實例】date_invert_choose DIC0 (a,a_invert,a_out); // 【不要忘了實例名!只有門級描述可以不寫】// 設置信號【設置輸入,看輸出】initialbegina = 1;a_invert = 0;#1 $display("功能%b,直接輸出:a_out = %b\n",a_invert,a_out);a_invert = 1;#1 $display("功能%b,取反輸出:a_out = %b\n",a_invert,a_out);endendmodule

2.1.3 功能驗證

仿真結果沒有問題!
在這里插入圖片描述

2.2 基礎加法器

2.2.1 設計塊

module add_base_1size (input a,b,          // 數據輸入input carry_in,     // 進位輸入output carry_out,   // 進位輸出output sum          // 和);assign sum = a ^ b ^ carry_in;assign carry_out = a&b | (a^b)&carry_in;endmodule

2.2.2 激勵塊

請讀者自行完成

2.2.3 功能驗證

經過仿真驗證,沒有問題。

2.3 1位加法器的實現

本節展現的是完整代碼,包含2.1和2.2的設計塊代碼
一位加法器內部

2.3.1 設計塊

`timescale 1ns / 1ps// 取反選擇器的設計
module date_invert_choose (input a,            // 數據輸入input a_invert,     // 使能端         output a_out        // 數據輸出);choose_2to1 CH0 (a,~a,a_invert,a_out);  // 調用二選一選擇器實例endmodule// 二選一選擇器
module choose_2to1 (input d0,d1,    // 數據輸入input add,      // 地址控制output out      // 數據輸出);assign out = (~add)&d0 | add&d1;endmodule// 基礎加法器
module add_base_1size (input a,b,          // 數據輸入input carry_in,     // 進位輸入output carry_out,   // 進位輸出output sum          // 和);assign sum = a ^ b ^ carry_in;assign carry_out = a&b | (a^b)&carry_in;endmodule// 1位加法器的實現
module add_1size (input a,b,      // 數據輸入input a_invert,b_invert,    //  求反控制input carry_in,     output carry_out,output sum);// 內部線網設置wire a_out,b_out;   // 獲得經過求反選擇器之后的結果// 調用模塊實例// 求反控制器實例date_invert_choose DateA (a,a_invert,a_out);date_invert_choose DateB (b,b_invert,b_out);// 加法器實例add_base_1size Add_A_B (a_out,b_out,carry_in,carry_out,sum);endmodule

2.3.2 激勵塊&功能驗證

module test;reg a,b;    // 注意reg為無符號數reg a_invert,b_invert;reg carry_in;wire carry_out;wire sum;add_1size AD0 (a,b,a_invert,b_invert,carry_in,carry_out,sum);// 設置信號,求 a + (-b)即 a - binitialbegina = 0;  b = 0;a_invert = 0;   b_invert = 1;   // b取反carry_in = 1;   // b取反加1#1 $display("a = %b,  b = %b,  carry_out = %b\na - b = %b\n",a,b,carry_out,sum); // 模擬 a - bif (sum == 0)$display("驗證成功! 0 - 0 = 0");endendmodule

在這里插入圖片描述
這里的驗證我有必要講解一下,因為有些地方會令人費解。

  1. reg為無符號數,如果直接像reg a = -1這樣的語法,存到計算機中是自動以補碼形式存儲的,那樣的話就沒有辦法驗證我們的設計了。要明白的一點是,我們是假定計算機不會自動將負數轉換為補碼,由我們的設計來實現這個工作,因此,這里我直接手動輸入了某個數的原碼,再有我們的設計將其轉換為補碼,這樣就完成了驗證工作。
  2. 我們假定在十進制下,a > 0,-b < 0,我們要求出 a + (-b)的值,并且這臺計算機沒有將-b存儲為補碼的功能,我們又知道b的二進制形式就是其補碼,它在經過全部按位取反再加1后,會得到-b的補碼,因此也就有了激勵塊中的b = 0;carry_in = 1;,這是為了驗證取反加1功能是否正確。
  3. 實際的過程是這樣的:a + b取反 + 1 = a + (-b) = a - b,這樣就是能夠讓你明白兩件事,負數的補碼轉換減法轉換為加法它的實際過程是這樣的:a = 0,b = 0,故a + b取反 + 1 = 0 + 1 + 1 = 10也就是sum = 0;carry_out = 1;

3 原理講解:實現整數減法,將負數轉換為補碼

本小節可以跳過,可以看完第4節再回看。

3.1 計算機進制數與人類進制數的差別

計算機進制數指的是

  • 二進制
  • 八進制
  • 十六進制

人類進制數指的是

  • 十進制

兩者差別主要在于,十進制數使用 -來表示負數,而計算機進制數使用補碼來表示負數,在其數據本身,就包含了符號,而十進制數據是不包含符號位的,它的符號位是單獨存在的。這也是機器數數據符號化的特點。

而人類又習慣于使用十進制,這才有了負數的補碼轉換方法及其硬件設計邏輯。

在這里重點強調,不要理會原碼、反碼,這是歷史上已經被淘汰的東西,他們跟補碼,只是有數學上的聯系,以及歷史原因。

但是,從十進制數轉換為補碼這一過程跟原碼、反碼完全沒有關系,很多教材和老師的講解都是不正確的。

我們只需要記住以下原則:

3.1.1 十進制數轉換為補碼的原理

請注意,這里十進制數的對象為:全體實數,包含整數和小數,他們都適用于補碼轉換規則,重要的一點區別是在計算機存儲上

  • 計算機存儲整數,直接使用補碼表示
  • 計算機存儲小數,使用的是浮點表示,關于這一點請詳細閱讀浮點運算的知識

在這里,我們以十進制整數為例來進行說明

  • 對于正數,這個非常容易,直接使用除基取余法即可,高位需要用0補全
    例如(假定寄存器為16位):
    200D = 0000_0000_1100_1000B
  • 對于負數,需要遵循這樣的規則:全部取反再加1

例如 -2D

(1)先表示出2D = 0000_0000_0000_0010B

(2)再全部取反,1111_1111_1111_1101B

(3)再加1,1111_1111_1111_1110B

(4)這樣得到的結果就是 -2D的補碼

需要注意的是,此時如果高位有空余,需要補上1,而不是0

其中,我之前提到的取反功能選擇器,就是完成了取反操作,但是還有加1操作呢?我們繼續看下一小節!

3.2 進位輸入信號carry_in的作用

我在1.1.1.1節提到過,carry_這個信號,初始需要置為0,加法器單獨存在一個的時候,它是不太重要的。

只有多個加法器連在一起(串行進位,第3節會提及)的時候,上一級的carry_in與下一級的carry_out連接起來,才能發揮作用。

但是,如果初始將carry_in置為1,就能夠發揮它的作用了,它在補碼轉換過程,起到了加1的作用。

無論輸入的數據是1位還是32位,加1只需要在最低位加1,也就是只需要把單獨存在的,不與carry_out連接的caryy_in置為1,就能實現加1操作

		  十進制的2:0000 0000 0000 0010先取反:   1111 1111 1111 1101再加1:   +                   1————————————————————————1111 1111 1111 1110
	其中:取反操作使用取反選擇器完成加1操作只需將carry_in置為1

這樣一來,取反選擇器與carry_in = 1緊密合作,就完成了十進制數到補碼的轉換,也就實現了整數的加減法。

備注:如果這個部分看不懂,請看完第3節再回看此節。

至此,我想你能夠理解實現整數減法的硬件設計原理了


思考點:

這里留一個問題給讀者思考,試想,如果采用大多數老師講解的原碼、反碼和補碼的原則去轉換補碼,硬件設計會是怎樣的?

這里我直接給你結果分析,具體設計不再講解,自行完成。
顯然,按照這樣的方式,設計會非常復雜,而且沒有必要,既違背了硬件設計簡單性原則,也增加了數學運算的復雜度

一般老師講解的原碼、反碼和補碼的轉換方式是

  • 先求原碼,再求反碼,再求補碼

我教你的是

  • 全部取反再加1

這二者是區別就是

  • 前者教你 1 + 10 - 9 = 2
  • 后者教你: 1 + 1 = 2

對比之下,哪個更加簡潔不言而喻,事實上,這些都是人為規定,怎么計算都可以,在數學上都說的通,但是要考慮硬件簡單性原則,后者顯然更加占優勢。


取反加1
假定a,b均為非負整數,則:
a - b = a + ( b取反 + 1 )

但是事實的情況往往會更加復雜,比如:-a - b又如何處理?

目前從原理上能夠實現減法,但這遠遠不夠,還需要根據實際需求進一步改進,這就涉及到了將其添加到MIPS指令上,這個以后再說。

3 建模:32位加法器

這里采用串行進位方式進行連接,并非并行進位(超前進位)

關于基礎加法器的超前進位實現,參照我的文章:全面剖析:加法器——從1位到4位,從一般加法(串行進位)到快速加法(并行進位/超前進位)【此處鏈接待完善】

3.1 科技黑箱:外部端口

32位加法器科技黑箱

3.2 揭秘黑箱:內部細節

內部細節

3.2.1 組合式設計的核心原則

  • 全部接口都連接,分三大類
    • 與外部總線連接
    • 與外部一根線連接
    • 內部相互連接(配置內部線網,一般為數組)

4 實現:32位加法器

32位加法器科技黑箱

4.1 設計塊

此處直接使用前面設計好的1位加法器,再次強調,此處為串行進位

module add_32sizes (input [31:0] a,b,input a_invert,b_invert,input carry_in,output carry_out,output [31:0] sum);// 設置內部線網wire carry_out_in [30:0];   // 內部串行進位傳遞// 調用模塊實例add_1size ADD0 (a[0],b[0],a_invert,b_invert,carry_in,carry_out_in[0],sum[0]);add_1size ADD1 (a[1],b[1],a_invert,b_invert,carry_out_in[0],carry_out_in[1],sum[1]);add_1size ADD2 (a[2],b[2],a_invert,b_invert,carry_out_in[1],carry_out_in[2],sum[2]);add_1size ADD3 (a[3],b[3],a_invert,b_invert,carry_out_in[2],carry_out_in[3],sum[3]);add_1size ADD4 (a[4],b[4],a_invert,b_invert,carry_out_in[3],carry_out_in[4],sum[4]);add_1size ADD5 (a[5],b[5],a_invert,b_invert,carry_out_in[4],carry_out_in[5],sum[5]);add_1size ADD6 (a[6],b[6],a_invert,b_invert,carry_out_in[5],carry_out_in[6],sum[6]);add_1size ADD7 (a[7],b[7],a_invert,b_invert,carry_out_in[6],carry_out_in[7],sum[7]);add_1size ADD8 (a[8],b[8],a_invert,b_invert,carry_out_in[7],carry_out_in[8],sum[8]);add_1size ADD9 (a[9],b[9],a_invert,b_invert,carry_out_in[8],carry_out_in[9],sum[9]);add_1size ADD10 (a[10],b[10],a_invert,b_invert,carry_out_in[9],carry_out_in[10],sum[10]);add_1size ADD11 (a[11],b[11],a_invert,b_invert,carry_out_in[10],carry_out_in[11],sum[11]); add_1size ADD12 (a[12],b[12],a_invert,b_invert,carry_out_in[11],carry_out_in[12],sum[12]);add_1size ADD13 (a[13],b[13],a_invert,b_invert,carry_out_in[12],carry_out_in[13],sum[13]);add_1size ADD14 (a[14],b[14],a_invert,b_invert,carry_out_in[13],carry_out_in[14],sum[14]);add_1size ADD15 (a[15],b[15],a_invert,b_invert,carry_out_in[14],carry_out_in[15],sum[15]);add_1size ADD16 (a[16],b[16],a_invert,b_invert,carry_out_in[15],carry_out_in[16],sum[16]);add_1size ADD17 (a[17],b[17],a_invert,b_invert,carry_out_in[16],carry_out_in[17],sum[17]);add_1size ADD18 (a[18],b[18],a_invert,b_invert,carry_out_in[17],carry_out_in[18],sum[18]);add_1size ADD19 (a[19],b[19],a_invert,b_invert,carry_out_in[18],carry_out_in[19],sum[19]);add_1size ADD20 (a[20],b[20],a_invert,b_invert,carry_out_in[19],carry_out_in[20],sum[20]);add_1size ADD21 (a[21],b[21],a_invert,b_invert,carry_out_in[20],carry_out_in[21],sum[21]);add_1size ADD22 (a[22],b[22],a_invert,b_invert,carry_out_in[21],carry_out_in[22],sum[22]);add_1size ADD23 (a[23],b[23],a_invert,b_invert,carry_out_in[22],carry_out_in[23],sum[23]);add_1size ADD24 (a[24],b[24],a_invert,b_invert,carry_out_in[23],carry_out_in[24],sum[24]);add_1size ADD25 (a[25],b[25],a_invert,b_invert,carry_out_in[24],carry_out_in[25],sum[25]);add_1size ADD26 (a[26],b[26],a_invert,b_invert,carry_out_in[25],carry_out_in[26],sum[26]);add_1size ADD27 (a[27],b[27],a_invert,b_invert,carry_out_in[26],carry_out_in[27],sum[27]);add_1size ADD28 (a[28],b[28],a_invert,b_invert,carry_out_in[27],carry_out_in[28],sum[28]);add_1size ADD29 (a[29],b[29],a_invert,b_invert,carry_out_in[28],carry_out_in[29],sum[29]);add_1size ADD30 (a[30],b[30],a_invert,b_invert,carry_out_in[29],carry_out_in[30],sum[30]);add_1size ADD31 (a[31],b[31],a_invert,b_invert,carry_out_in[30],carry_out,sum[31]);endmodule

4.2 激勵塊

注意,因為在Verilog中,reg自動以二進制補碼形式存儲,所以此處驗證負數的時候,我們假定計算機沒有以補碼存儲這一功能,我們假定b = -5,并且手動設置b的值,將b的值設置為5的補碼,5的補碼就是其二進制表示0101B,以此來驗證5的補碼經過全部取反加1后,是否變成了-5的補碼,從而驗證了設計的正確性。

如果你沒有看懂,那么請看完第6節的補充鏈接,再回顧此內容。

module test;reg [31:0] a,b;    // 注意reg為無符號數reg a_invert,b_invert;integer carry_in;wire carry_out;wire [31:0] sum;add_32sizes AD0 (a,b,a_invert,b_invert,carry_in,carry_out,sum);// 設置信號,假設b = -5;a = 8;求a + b initialbegina = 4'b1000;    // 8的補碼b = 4'b0101;    // reg為無符號數,自動把-5存為補碼,無法驗證結果,因此使用 |-5| = 5 的補碼a_invert = 0;   b_invert = 1;   // b取反carry_in = 1;   // b取反加1#1 $display("a = %d,  b = -%d\na + b = %d\n",a,b,sum); // 模擬 a - bif(sum == 3)$display("驗證成功! 8 + (- 5) = 3");endendmodule

4.2.1 報錯解決方案

對于這樣的錯誤:[XSIM 43-3238] Failed to link the design.

通常情況下,是因為激勵塊與設計塊的連接出了問題,可能是

  • 模塊調用錯誤
  • 模塊忘記實例化
  • 模塊接口連接錯誤

可以按照這個思路依次排查

4.3 仿真驗證

在這里插入圖片描述

5 行為級建模的魅力

前面說了那么多,其實,真正硬件編程的時候沒有那么麻煩,強大的EDA工具讓我們能夠只需要描述其行為,就能完成設計,這是抽象層次足夠高的設計,讓我們來看一下。

這里你可能想要摔電腦了,什么????我做了這么半天,實際上只需要幾行??那你寫了這么多有啥用!!

冷靜一下,仔細想一下,你是不是在之前的操作中,對于加法器已經非常熟悉了?如果你認真做了,我想應該是的,這就是Learning by doing,在做中學,能夠快速掌握知識,加深對于知識的理解程度,這一點是很必要的,因此你必須花時間來完成它。

5.1 設計塊

module add_32bits(input [31:0] a,b,input ADDctl,   // 控制端,用于識別加減法 0代表加法,1代表減法output reg [31:0] result);always @(a,b,ADDctl)begincase(ADDctl)0: result = a + b;1: result = a - b;endcaseendendmodule

5.2 激勵塊

module test;// reg signed [31:0] a,b;integer a,b;reg ADDctl;wire signed [31:0] result;add_32bits ADD_0 (a,b,ADDctl,result);initialbegin// 測試加法a = -1;  b = 20;     ADDctl = 0;#1 $display("%d + %d = %d",a,b,result);#1// 測試減法  【1-20= 溢出值,因為不識別補碼!???怎么辦】a = -10;  b = 28;     ADDctl = 1;#1 $display("%d - %d = %d",a,b,result);endendmodule

5.3 結果驗證

在這里插入圖片描述

5.4 思考點

  1. reg類型將負數以補碼存儲,實現了減法變為加法,那么Verilog中為何還有減法運算?
  2. Verilog中負數以補碼形式存儲,令其以%d形式輸出的時候,并不會顯示負數,而是顯示一個超大的正數,如何解決?
  3. 如何正確顯示激勵塊輸入的負數,輸入端口的reg類型,可否使用integer類型?

以上問題,看完下一小結的擴展鏈接,你就能得知答案。

6 由行為級描述掌握幾大重要思想

設計的思想有

  • 分治思想
  • 歸一思想
  • 實戰驗證思維
  • 查閱資料的能力

我單獨寫了一篇文章,以闡述一些重要的理論和思想。請看:待完善

7 待求解決方案的錯誤

[XSIM 43-3345] Unable to remove previous simulation file xsim.dir/test_behav/xsimk.exe. Please check if you have another instance of this simulation running on your system, terminate it and then recompile your design. System Error Message: boost::filesystem::status: 拒絕訪問。: "xsim.dir/test_behav/xsimk.exe".

[XSIM 43-3238] Failed to link the design.

我不知道為什么會拒絕訪問,并且此狀態下,系統不能刪除文件,唯一的辦法就是重新建立一個文件,并且將設計塊和激勵塊copy過去。

問題待解決中!如有讀者知道解決方案,歡迎私聊我~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/384770.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/384770.shtml
英文地址,請注明出處:http://en.pswp.cn/news/384770.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

線程間通信————互斥

互斥 臨界資源 一次只允許一個任務&#xff08;進程&#xff0c;線程)訪問的共享資源 臨界區 訪問臨界資源的代碼 互斥機制 mutex互斥鎖 任務訪問臨界資源前申請鎖 訪問完后釋放鎖 互斥鎖初始化 #include <pthread.h> int pthread_mutex_init(pthread_mutex_t *mute…

【Verilog HDL】門級描述 / 數據流描述 / 行為級描述——通過四選一多路選擇器,實現對于不同層級描述方式的整體性認知

目錄0 前言1 輸出端口的設計1.1 門級描述和數據流描述1.2 行為級描述2 三種描述方式的整體架構2.1 門級描述2.2 數據流描述2.3 行為級描述2.4 補充&#xff1a;獨立的語句2.5 小結3 理解三種描述方式的本質3.1 門級描述3.2 數據流描述3.3 行為級描述4 理解不同抽象層級描述方式…

線程創建-結束-回收 教程

ps aux -L 查看線程信息 且顯示進程狀態 使用進程的缺點: 進程切換 系統開銷較大 開銷大的原因 &#xff1a;切換時需要頻繁刷新 cache(類似于緩沖區) 和TLB linux不區分線程 進程 線程其實也屬于進程 只不過是特殊的進程 是一種可以共享地址空間的進程 使用線程的優點&#x…

【匯編語言】匯編實驗IDE(集成開發環境):RadASM的安裝和使用說明

0 前言 本文適合8086CPU的指令集。 對于重要的專業基礎課程&#xff0c;匯編語言&#xff0c;做實驗是必不可少的&#xff0c;但是由于匯編語言本身的缺陷&#xff0c;現代計算機并不能直接運行匯編語言程序&#xff0c;因此&#xff0c;一般老師會要求我們 使用虛擬機&…

【匯編語言】理解8086CPU中,不同類型的寄存器和匯編指令規則的聯系(會繼續更新)

0 前言 你是否因為匯編指令繁雜的規則而苦惱呢&#xff1f;作者本人也很煩&#xff0c;因為往往教材中只告訴我們規則&#xff0c;卻不告訴我們為什么&#xff0c;沒有原因就直接記憶&#xff0c;負擔太大&#xff0c;后期靈活運用也增添阻力&#xff0c;因此&#xff0c;我經…

System V IPC之信號燈

信號燈也叫信號量 用于進程/線程同步或互斥的機制 信號燈的類型 1.Posix 無名信號燈 2.Posix 有名信號燈 3.System V 信號燈 信號燈的含義 計數信號燈&#xff08;1和2都是&#xff09; System V信號燈是一個或多個計數信號燈的集合&#xff08;可操作集合中的多個信號燈&…

【VS 2017 C語言 匯編語言】如何使用VS 2017,通過反匯編查看C語言代碼對應的32位x86匯編語言 VS 2017單步調試的使用

0 前言 本文適用于VS的大多數版本&#xff0c;本文以VS 2017為例進行講解。 1 編輯C語言代碼 首先&#xff0c;在VS編譯器中&#xff0c;創建項目&#xff0c;敲一段C語言代碼&#xff0c;這個過程不解釋了&#xff0c;如果不會請百度。 #include <stdio.h> #include…

System V IPC之共享內存

共享內存是一種最為高效的進程間通信方式&#xff0c;進程可以直接讀寫內存&#xff0c; 而不需要任何數據的拷貝 共享內存在內核空間創建&#xff0c; 可以被進程映射到用戶空間訪問 由于多個進程可同時訪問共享內存 &#xff0c; 因此需要同步和互斥機制配合使用 共享內存的使…

【匯編語言】結合C語言,使用VS 2017調試模式下的反匯編工具學習32位x86匯編指令

0 前言 簡要說明x86系列指令集的整體概況與變化。 我給到你補充學習內容&#xff1a;使用VS學習匯編語言的教程 1 8086CPU到現代CPU的變化 做一些了解即可&#xff0c;不是絕對的&#xff0c;取決于設計工藝以及用途&#xff0c;不同計算機不一樣也正常。 1.1 CPU位數與地…

System V IPC之消息隊列

消息隊列由消息隊列id來唯一標識 消息隊列就是一個消息的列表 用戶可以在消息隊列中添加消息 讀取消息 消息隊列可以按照類型來發送和接收消息 消息隊列使用步驟 打開/創建消息隊列 msgget 向消息隊列發送消息 msgsnd 從消息隊列接收消息 msgrcv 控制消息隊列 msgctl 創建/打開…

【匯編語言】學習源頭知識:XLAT指令的本質(待更新)

0 前言 帶你理解XLAT指令的本質. 我想讓你清楚的是&#xff0c;XLAT指令 本質就是數據的傳送&#xff1a;本質就是完成mov指令的傳送功能&#xff0c;只不過源操作數的尋址方式是[bxal]&#xff0c;目標操作數是al表象是數據的轉換&#xff1a;例如將十六進制轉換為ASCII字符…

進程間通信————信號

信號 信號是在軟件層次上對中斷機制的一直模擬&#xff0c;是一種異步通信方式 linux內核通過信號通知用戶進程&#xff0c; 不同的信號類型代表不同的事件 進程對信號有不同的響應方式 缺省方式 忽略信號 捕捉信號 SIGKILL和SIGSTOP這兩個信號量 級別很高 只能執行默認操作…

【匯編語言】清華大學學堂在線《匯編語言程序設計》課程學習筆記

0 前言 全是基于x86系列處理器 1 寄存器與存儲器的區別 2 匯編程序員眼中的系統結構 指令寄存器 PC&#xff08;Program Counter&#xff09; 指向下一條指令的地址 16位 CS:IP32位 EIP64位 RIP 寄存器與寄存器堆&#xff08;Registers&#xff09; 在處理器內部以名字方…

進程間通信————無名管道

無名管道 只能用于具有親緣關系的進程之間的通信 單工的通信模式 具有固定的讀端和寫端 無名管道創建時會返回兩個文件描述符 分別用于讀寫管道 只能用于親屬關系之間 創建無名管道 #include <unistd.h> int pipe(int pfd[2]) 成功返回0 失敗返回EOF pfd包含兩個元素的…

什么是計算機思維?2個簡單表達式讓你理解!

0 前言 本文以十進制整數為例&#xff0c;使用2個最簡單的表達式char a -20;和char c a b;,為你深入淺出地講解計算機思維&#xff0c;力求將抽象的計算機思維具象化講解&#xff0c;同時&#xff0c;我將為你描述一個宏大的計算機世界的藍圖。 計算機思維與核心思想概要&a…

進程間通信————有名管道

有名管道 特點&#xff1a; 對應管道文件 可用于任意進程之間進行通信 打開管道時 可指定讀寫方式 通過文件I/O操作 內容存放在內存中 當讀端和寫端都不存在 管道內容自動釋放 當讀端和寫端只存在一個 將會無法打開管道文件 管道文件大小永遠為0 因為管道中的內容保存在內…

【匯編語言】8086匯編的loop循環與[bx]尋址(王爽第五章5.5節學習筆記)

計算FFFF:0 ~ FFFF:B單元中數據的和&#xff0c;結果存儲到dx中 1 分析與解決 內存單元&#xff1a;字節型數據目標寄存器&#xff1a;dx&#xff0c;字型寄存器&#xff0c;不匹配數據范圍&#xff1a;dx不會超&#xff0c;但是dl會超&#xff0c;因此必須用dx將字節型數據&a…

Linux下數據庫(sqlite3)學習筆記

sqlite3 數據庫安裝 1. 本地安裝 sudo dpkg -i *.deb 2.在線安裝 sudo apt-get install sqlite3 3.使用壓縮包解壓 壓縮包下載路徑&#xff1a;鏈接&#xff1a;https://pan.baidu.com/s/1xHLZGObQODUGBReNEi3KKQ 提取碼&#xff1a;zjqv SQLITE3 基本命令 兩種命令 1.以…

【匯編語言】8086、x86-32和C語言【賦值語句 和 數組】的對比學習(王爽學習筆記:5.8段前綴的使用)

0 前言 這里給出兩種思路&#xff0c;都比王爽老師書上的做法要簡單高效&#xff0c;事實上&#xff0c;理解指令的本質&#xff0c;就能達到靈活應用&#xff0c;這樣才能打破規則 題目&#xff1a;將內存ffff:0 - ffff:b的數據&#xff0c;復制到內存ffff:10 - ffff:1b中 備…

signal------SIGCHLD

因為筆者之前的文章里面有錯誤&#xff0c;今天發現&#xff0c;立馬做個修改。在下面我的一段關于sigchld信號相對于直接調用wait函數的好處時&#xff0c;我說調用wait函數要一直檢測子進程是否執行完其實是錯誤的&#xff0c; wait是阻塞函數&#xff0c;當主進程調用wait函…