週刊 TD4をFPGAで創る 第4号 「ALUを創る」
第8章からです。頑張って記事を書くぞ!
1.74HC283
というわけで4bit Full-Adder。P信号,G信号を使ってCarry-LookaheadなAdderにするって奴はテストによく出るよ!
module LOGIC_74HC283(CIN, A1, A2, A3, A4, B1, B2, B3, B4, S1, S2, S3, S4, COUT); input CIN, A1, A2, A3, A4, B1, B2, B3, B4; output S1, S2, S3, S4, COUT; wire [3:0] G; wire [3:0] P; wire [3:0] C; assign G[0] = ~(A1 & B1); assign G[1] = ~(A2 & B2); assign G[2] = ~(A3 & B3); assign G[3] = ~(A4 & B4); assign P[0] = ~(A1 | B1); assign P[1] = ~(A2 | B2); assign P[2] = ~(A3 | B3); assign P[3] = ~(A4 | B4); assign C[0] = CIN; assign C[1] = ~((~CIN & G[0]) | P[0]); assign C[2] = ~((~CIN & G[0] & G[1]) | (G[1] & P[0]) | P[1]); assign C[3] = ~((~CIN & G[0] & G[1] & G[2]) | (G[1] & G[2] & P[0]) | (G[2] & P[1]) | P[2]); assign COUT = ~((~CIN & G[0] & G[1] & G[2] & G[3]) | (G[1] & G[2] & G[3] & P[0]) | (G[2] & G[3] & P[1]) | (G[3] & P[2]) | P[3]); assign S1 = (C[0] ^ (~P[0] & G[0])); assign S2 = (C[1] ^ (~P[1] & G[1])); assign S3 = (C[2] ^ (~P[2] & G[2])); assign S4 = (C[3] ^ (~P[3] & G[3])); endmodule
テストベンチはこんな感じ?
module logic_74hc283_test; reg CIN; reg [3:0] A; reg [3:0] B; wire [3:0] S; wire COUT; LOGIC_74HC283 logic_74hc283(CIN, A[0], A[1], A[2], A[3], B[0], B[1], B[2], B[3], S[0], S[1], S[2], S[3], COUT); initial begin $dumpfile("logic_74hc283_test.vcd"); $dumpvars(0, logic_74hc283_test); $monitor ("%t: A = %d, B = %d, CIN = %b, S = %d, COUT = %b", $time, A, B, CIN, S, COUT); CIN = 0; A = 0; B = 0; #10 A = 1; B = 1; #10 A = 1; B = 2; #10 A = 2; B = 3; #10 A = 4; B = 2; #10 A = 4; B = 3; #10 A = 4; B = 5; #10 A = 8; B = 10; #10 A = 6; B = 7; #10 A = 12; B = 9; #10 $finish; end endmodule
番外編
2.74HC181
物理的になくても,Verilogで書くことならできちゃうんです。簡単にね!回路図はこんな感じです。
まったく,わけがわからないよ。
でも,なんとなーく,左右にわかれてますよね?よね?
色をつけるとわかりやすい!
それじゃあ元気よく実装しましょう!(半泣)
module LOGIC_74HC181(CIN, S0, S1, S2, S3, M, A0, A1, A2, A3, B0, B1, B2, B3, F0, F1, F2, F3, COUT, COMP, G, P); input CIN, S0, S1, S2, S3, M, A0, A1, A2, A3, B0, B1, B2, B3; output F0, F1, F2, F3, COUT, COMP, G, P; wire [3:0] D; wire [3:0] E; wire [3:0] F; assign D[0] = ~((~B0 & S1) | (B0 & S0) | A0); assign D[1] = ~((~B1 & S1) | (B1 & S0) | A1); assign D[2] = ~((~B2 & S1) | (B2 & S0) | A2); assign D[3] = ~((~B3 & S1) | (B3 & S0) | A3); assign E[0] = ~((B0 & S3 & A0) | (A0 & S2 & ~B0)); assign E[1] = ~((B1 & S3 & A1) | (A1 & S2 & ~B1)); assign E[2] = ~((B2 & S3 & A2) | (A2 & S2 & ~B2)); assign E[3] = ~((B3 & S3 & A3) | (A3 & S2 & ~B3)); assign F0 = ((D[0] ^ E[0]) ^ ~(CIN & ~M)); assign F1 = ((D[1] ^ E[1]) ^ ~((CIN & E[0] & ~M) | (D[0] & ~M))); assign F2 = ((D[2] ^ E[2]) ^ ~((CIN & E[0] & E[1] & ~M) | (E[1] & D[0] & ~M) | (D[1] & ~M))); assign F3 = ((D[3] ^ E[3]) ^ ~((CIN & E[0] & E[1] & E[2] & ~M) | (E[1] & E[2] & D[0] & ~M) | (E[2] & D[1] & ~M) | (D[2] & ~M))); assign P = ~(E[0] & E[1] & E[2] & E[3]); assign G = ~(D[3] | (E[3] & D[2]) | (E[3] & E[2] & D[1]) | (E[3] & E[2] & E[1] & D[0])); assign COMP = F0 & F1 & F2 & F3; assign COUT = ~G | (E[3] & E[2] & E[1] & E[0] & CIN); endmodule
網羅テストを実行するのはさすがに無理だと思うので,適当にテストベンチ書いてテストしてみるといいよ!
あと,このICはActive-LowとActive-Highで挙動が違うから注意してね!
詳しいことはデータシート読め!
番外編終わり
3.74HC74
フラグレジスタ用のフリップフロップ回路です。奥さん!二個入りニコニコ大特価だよ!
module LOGIC_74HC74(CLR1, D1, CK1, PR1, Q1, Qb1, CLR2, D2, CK2, PR2, Q2, Qb2); input CLR1, D1, CK1, PR1, CLR2, D2, CK2, PR2; output Q1, Qb1, Q2, Qb2; reg Q1, Q2; assign Qb1 = ~Q1; assign Qb2 = ~Q2; initial begin Q1 <= 1'b0; Q2 <= 1'b0; end always @(CLR1, CK1, PR1, CLR2, CK2, PR2) begin if(~CLR1) begin Q1 <= 1'b0; end else if(~PR1) begin Q1 <= 1'b1; end else if(CK1) begin Q1 <= D1; end if(~CLR2) begin Q2 <= 1'b0; end else if(~PR2) begin Q2 <= 1'b1; end else if(CK2) begin Q2 <= D2; end end endmodule
テストベンチはこんな感じ?
module logic_74hc74_test; reg CLR1, D1, CK1, PR1, CLR2, D2, CK2, PR2; wire Q1, Qb1, Q2, Qb2; LOGIC_74HC74 logic_74hc74(CLR1, D1, CK1, PR1, Q1, Qb1, CLR2, D2, CK2, PR2, Q2, Qb2); initial begin $dumpfile("logic_74hc74_test.vcd"); $dumpvars(0, logic_74hc74_test); $monitor ("%t: CK1 = %b, (CLR1, PR1) = (%b, %b), D1 = %b, Q1 = %b | CK2 = %b, (CLR2, PR2) = (%b, %b), D2 = %b, Q2 = %b", $time, CK1, CLR1, PR1, D1, Q1, CK2, CLR2, PR2, D2, Q2); CK1 = 0; CK2 = 0; CLR1 = 1; CLR2 = 1; PR1 = 1; PR2 = 1; D1 = 0; D2 = 0; #3 D1 = 1; D2 = 1; #1 D1 = 0; D2 = 0; #30 $finish; end always #3 CK1 = ~CK1; always #5 CK2 = ~CK2; endmodule
4.8.2節までの回路
というわけで,8.2節までの回路(つまり,I/Oポートなし)を書いてみます。module CHAPTER_8_2(CLOCK, RESET, SELECT_A, SELECT_B, LOAD_0, LOAD_1, LOAD_2, LOAD_3, ROM_DATA, ROM_ADDRESS); input CLOCK, RESET; input SELECT_A, SELECT_B, LOAD_0, LOAD_1, LOAD_2, LOAD_3; input [7:0] ROM_DATA; output [3:0] ROM_ADDRESS; reg Vcc = 1'b1; reg GND = 1'b0; wire [6:0] NOT_IN_USE; wire [3:0] REGISTER_IN; wire [3:0] REGISTER_A_OUT; wire [3:0] REGISTER_B_OUT; wire [3:0] REGISTER_C_OUT; wire [3:0] REGISTER_D_OUT; wire [3:0] ALU_IN_A; wire [3:0] ALU_IN_B; wire CARRY_OUT, C_FLAG; wire [3:0] OPERATION_CODE; wire [3:0] IMEEDIATE_DATA; assign ROM_ADDRESS = REGISTER_D_OUT; assign OPERATION_CODE = ROM_DATA[7:4]; assign IMEEDIATE_DATA = ROM_DATA[3:0]; assign ALU_IN_B = IMEEDIATE_DATA; LOGIC_74HC161 Register_A (RESET, CLOCK, REGISTER_IN[0], REGISTER_IN[1], REGISTER_IN[2], REGISTER_IN[3], GND, LOAD_0, GND, REGISTER_A_OUT[0], REGISTER_A_OUT[1], REGISTER_A_OUT[2], REGISTER_A_OUT[3], NOT_IN_USE[0]); LOGIC_74HC161 Register_B (RESET, CLOCK, REGISTER_IN[0], REGISTER_IN[1], REGISTER_IN[2], REGISTER_IN[3], GND, LOAD_1, GND, REGISTER_B_OUT[0], REGISTER_B_OUT[1], REGISTER_B_OUT[2], REGISTER_B_OUT[3], NOT_IN_USE[1]); LOGIC_74HC161 Register_C (RESET, CLOCK, REGISTER_IN[0], REGISTER_IN[1], REGISTER_IN[2], REGISTER_IN[3], GND, LOAD_2, GND, REGISTER_C_OUT[0], REGISTER_C_OUT[1], REGISTER_C_OUT[2], REGISTER_C_OUT[3], NOT_IN_USE[2]); LOGIC_74HC161 Register_D (RESET, CLOCK, REGISTER_IN[0], REGISTER_IN[1], REGISTER_IN[2], REGISTER_IN[3], Vcc, LOAD_3, Vcc, REGISTER_D_OUT[0], REGISTER_D_OUT[1], REGISTER_D_OUT[2], REGISTER_D_OUT[3], NOT_IN_USE[3]); LOGIC_74HC153 Register_Selector_0 (SELECT_A, SELECT_B, GND, GND, REGISTER_A_OUT[0], REGISTER_B_OUT[0], REGISTER_C_OUT[0], GND, REGISTER_A_OUT[1], REGISTER_B_OUT[1], REGISTER_C_OUT[1], GND, ALU_IN_A[0], ALU_IN_A[1]); LOGIC_74HC153 Register_Selector_1 (SELECT_A, SELECT_B, GND, GND, REGISTER_A_OUT[2], REGISTER_B_OUT[2], REGISTER_C_OUT[2], GND, REGISTER_A_OUT[3], REGISTER_B_OUT[3], REGISTER_C_OUT[3], GND, ALU_IN_A[2], ALU_IN_A[3]); LOGIC_74HC283 ALU (GND, ALU_IN_A[0], ALU_IN_A[1], ALU_IN_A[2], ALU_IN_A[3], ALU_IN_B[0], ALU_IN_B[1], ALU_IN_B[2], ALU_IN_B[3], REGISTER_IN[0], REGISTER_IN[1], REGISTER_IN[2], REGISTER_IN[3], CARRY_OUT); LOGIC_74HC74 C_Flag (RESET, CARRY_OUT, CLOCK, Vcc, C_FLAG, NOT_IN_USE[4], GND, GND, GND, GND, NOT_IN_USE[5], NOT_IN_USE[6]); endmodule
だいぶCPUっぽくなってきましたね!
4.8.3節までの回路
どんどんいってみましょう!8.3節までの回路(つまり,I/Oポートつき)を書いてみます。
module CHAPTER_8_3(CLOCK, RESET, SELECT_A, SELECT_B, LOAD_0, LOAD_1, LOAD_2, LOAD_3, ROM_DATA, ROM_ADDRESS); input CLOCK, RESET; input SELECT_A, SELECT_B, LOAD_0, LOAD_1, LOAD_2, LOAD_3; input [7:0] ROM_DATA; output [3:0] ROM_ADDRESS; reg Vcc = 1'b1; reg GND = 1'b0; wire [6:0] NOT_IN_USE; wire [3:0] REGISTER_IN; wire [3:0] REGISTER_A_OUT; wire [3:0] REGISTER_B_OUT; wire [3:0] REGISTER_C_OUT; wire [3:0] REGISTER_D_OUT; wire [3:0] ALU_IN_A; wire [3:0] ALU_IN_B; wire CARRY_OUT, C_FLAG; wire [3:0] OPERATION_CODE; wire [3:0] IMEEDIATE_DATA; assign ROM_ADDRESS = REGISTER_D_OUT; assign OPERATION_CODE = ROM_DATA[7:4]; assign IMEEDIATE_DATA = ROM_DATA[3:0]; assign ALU_IN_B = IMEEDIATE_DATA; assign OUTPUT = REGISTER_C_OUT; LOGIC_74HC161 Register_A (RESET, CLOCK, REGISTER_IN[0], REGISTER_IN[1], REGISTER_IN[2], REGISTER_IN[3], GND, LOAD_0, GND, REGISTER_A_OUT[0], REGISTER_A_OUT[1], REGISTER_A_OUT[2], REGISTER_A_OUT[3], NOT_IN_USE[0]); LOGIC_74HC161 Register_B (RESET, CLOCK, REGISTER_IN[0], REGISTER_IN[1], REGISTER_IN[2], REGISTER_IN[3], GND, LOAD_1, GND, REGISTER_B_OUT[0], REGISTER_B_OUT[1], REGISTER_B_OUT[2], REGISTER_B_OUT[3], NOT_IN_USE[1]); LOGIC_74HC161 Register_C (RESET, CLOCK, REGISTER_IN[0], REGISTER_IN[1], REGISTER_IN[2], REGISTER_IN[3], GND, LOAD_2, GND, REGISTER_C_OUT[0], REGISTER_C_OUT[1], REGISTER_C_OUT[2], REGISTER_C_OUT[3], NOT_IN_USE[2]); LOGIC_74HC161 Register_D (RESET, CLOCK, REGISTER_IN[0], REGISTER_IN[1], REGISTER_IN[2], REGISTER_IN[3], Vcc, LOAD_3, Vcc, REGISTER_D_OUT[0], REGISTER_D_OUT[1], REGISTER_D_OUT[2], REGISTER_D_OUT[3], NOT_IN_USE[3]); LOGIC_74HC153 Register_Selector_0 (SELECT_A, SELECT_B, GND, GND, REGISTER_A_OUT[0], REGISTER_B_OUT[0], REGISTER_C_OUT[0], GND, REGISTER_A_OUT[1], REGISTER_B_OUT[1], REGISTER_C_OUT[1], GND, ALU_IN_A[0], ALU_IN_A[1]); LOGIC_74HC153 Register_Selector_1 (SELECT_A, SELECT_B, GND, GND, REGISTER_A_OUT[2], REGISTER_B_OUT[2], REGISTER_C_OUT[2], GND, REGISTER_A_OUT[3], REGISTER_B_OUT[3], REGISTER_C_OUT[3], GND, ALU_IN_A[2], ALU_IN_A[3]); LOGIC_74HC283 ALU (GND, ALU_IN_A[0], ALU_IN_A[1], ALU_IN_A[2], ALU_IN_A[3], ALU_IN_B[0], ALU_IN_B[1], ALU_IN_B[2], ALU_IN_B[3], REGISTER_IN[0], REGISTER_IN[1], REGISTER_IN[2], REGISTER_IN[3], CARRY_OUT); LOGIC_74HC74 C_Flag (RESET, CARRY_OUT, CLOCK, Vcc, C_FLAG, NOT_IN_USE[4], GND, GND, GND, GND, NOT_IN_USE[5], NOT_IN_USE[6]); endmodule
次回予告
ついにシミュレーション編最終回!命令デコーダを完成させます!
そして,全てを結合させCPU全体の完成です!
乞うご期待!!!
Amazon.co.jp - 渡波 郁 「CPUの創りかた」 毎日コミュニケーションズ (2003)
Best No Deposit Bonus Codes in India - Herzamanindir.com
返信削除5 steps1.Visit nba매니아 the official casino-roll.com website of No Deposit India.
Benefits of using a no deposit bonus.
Benefits of using a no deposit bonus.
Benefits of using herzamanindir a no apr casino deposit bonus.
Online Sincere sol.edu.kg Accessory domain www.online-bookmakers.info