2012年9月6日木曜日

週刊 TD4をFPGAで創る 第3号 「レジスタを創る」

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

コメントを投稿