週刊 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 件のコメント:
コメントを投稿