週刊 TD4をFPGAで創る 第3号 「レジスタを創る」
第7章からです。え,第6章? ちゃんと読んでおいてね!
1.74HC153
4チャネルのデータセレクタですね。真理表はデータシートでも参照してくださいな。
module LOGIC_74HC153(A, B, G1, G2, C10, C11, C12, C13, C20, C21, C22, C23, Y1, Y2); input A, B, G1, G2, C10, C11, C12, C13, C20, C21, C22, C23; output Y1, Y2; wire [3:0] temp [0:1]; assign temp[0][0] = C10 & (~B) & (~A) & (~G1); assign temp[0][1] = C11 & (~B) & A & (~G1); assign temp[0][2] = C12 & B & (~A) & (~G1); assign temp[0][3] = C13 & B & A & (~G1); assign temp[1][0] = C20 & (~B) & (~A) & (~G2); assign temp[1][1] = C21 & (~B) & A & (~G2); assign temp[1][2] = C22 & B & (~A) & (~G2); assign temp[1][3] = C23 & B & A & (~G2); assign Y1 = temp[0][0] | temp[0][1] | temp[0][2] | temp[0][3]; assign Y2 = temp[1][0] | temp[1][1] | temp[1][2] | temp[1][3]; endmodule
テストベンチはこんな感じ?
module logic_74hc153_test; reg A, B; reg [1:0] G; reg [3:0] C0; reg [3:0] C1; wire [1:0] Y; LOGIC_74HC153 logic_74hc153(A, B, G[0], G[1], C0[0], C0[1], C0[2], C0[3], C1[0], C1[1], C1[2], C1[3], Y[0], Y[1]); initial begin $dumpfile("logic_74hc153_test.vcd"); $dumpvars(0, logic_74hc153_test); $monitor ("%t: (B, A) = (%b, %b), G = (%b, %b), C0 = %b%b%b%b, C1 = %b%b%b%b, Y = (%b, %b)", $time, B, A, G[0], G[1], C0[0], C0[1], C0[2], C0[3], C1[0], C1[1], C1[2], C1[3], Y[0], Y[1]); G = 3; B = 0; A = 0; C0 = 4'b1100; C1 = 4'b0101; #10 B = 0; A = 0; #10 B = 0; A = 1; #10 B = 1; A = 0; #10 B = 1; A = 1; #10 $finish; end endmodule
2.74HC161
4ビットカウンタです。こいつをレジスタとして使います。
module LOGIC_74HC161(CLR, CK, A, B, C, D, ENP, LOAD, ENT, QA, QB, QC, QD, CO); input CLR, CK, A, B, C, D, ENP, LOAD, ENT; output QA, QB, QC, QD, CO; wire [3:0] DATA = {D, C, B, A}; reg [3:0] FLIPFLOP; assign QA = FLIPFLOP[0]; assign QB = FLIPFLOP[1]; assign QC = FLIPFLOP[2]; assign QD = FLIPFLOP[3]; assign CO = ENT & QA & QB & QC & QD; initial begin FLIPFLOP <= 4'b0000; end always @(CLR or posedge CK) begin if(~CLR) begin FLIPFLOP <= 4'b0000; end else if(CK) begin if(~LOAD) begin FLIPFLOP <= DATA; end else if(ENP & ENT) begin if(FLIPFLOP == 4'b1111) begin FLIPFLOP <= 4'b0000; end else begin FLIPFLOP <= FLIPFLOP + 1; end end end end endmodule
テストベンチはこんな感じ?
module logic_74hc161_test; reg CLR, CK, ENP, LOAD, ENT; reg [3:0] DATA; wire A, B, C, D, QA, QB, QC, QD, CO; wire [3:0] Q; assign A = DATA[0]; assign B = DATA[1]; assign C = DATA[2]; assign D = DATA[3]; assign Q = {QD, QC, QB, QA}; LOGIC_74HC161 logic_74hc161(CLR, CK, A, B, C, D, ENP, LOAD, ENT, QA, QB, QC, QD, CO); initial begin $dumpfile("a.vcd"); $dumpvars(0, logic_74hc161_test); $monitor ("%t: CK = %b, (CLR, LOAD, ENP, ENT) = (%b %b %b %b), DATA = %d(%b%b%b%b), Q = %d(%b%b%b%b), CO = %b", $time, CK, CLR, LOAD, ENP, ENT, DATA, D, C, B, A, Q, QD, QC, QB, QA, CO); CK = 0; CLR = 1; ENP = 1; LOAD = 1; ENT = 1; DATA = 0; #60 #10 CLR = 0; #10 CLR = 1; #60 DATA = 0; #10 DATA = 7; LOAD = 0; #10 DATA = 0; LOAD = 1; #10 DATA = 0; #40 ENP = 0; #30 ENP = 1; #210 #10 $finish; end always #10 CK = ~CK; endmodule
3.第7章の章末の回路
第7章の章末の回路を実装してみましょう!module CHAPTER_7(CLOCK, RESET, SELECT_A, SELECT_B, LOAD_0, LOAD_1, LOAD_2, LOAD_3); input CLOCK, RESET; input SELECT_A, SELECT_B, LOAD_0, LOAD_1, LOAD_2, LOAD_3; reg GND = 1'b0; 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] NOT_IN_USE; 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_0, 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_0, 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], GND, LOAD_0, GND, 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], REGISTER_D_OUT[0], REGISTER_A_OUT[1], REGISTER_B_OUT[1], REGISTER_C_OUT[1], REGISTER_D_OUT[1], REGISTER_IN[0], REGISTER_IN[1]); LOGIC_74HC153 Register_Selector_1 (SELECT_A, SELECT_B, GND, GND, REGISTER_A_OUT[2], REGISTER_B_OUT[2], REGISTER_C_OUT[2], REGISTER_D_OUT[2], REGISTER_A_OUT[3], REGISTER_B_OUT[3], REGISTER_C_OUT[3], REGISTER_D_OUT[3], REGISTER_IN[2], REGISTER_IN[3]); endmodule
こいつは,outputがないのでテストのしようがないですねぇ。。。
まぁ,REGISTER_A_OUTとかを無理やり出力に引っ張ればいいんですけど。
面倒なんで,テストしたい人はやって見るといいと思います。
次回予告
次はいよいよALUだよ!演算回路だよ!
CPUっぽいよ!
Amazon.co.jp - 渡波 郁 「CPUの創りかた」 毎日コミュニケーションズ (2003)
0 件のコメント:
コメントを投稿