110 likes | 271 Views
計算機アーキテクチャ演習第5回 Verilog 特訓. 慶應義塾大学 理工学部 情報工学科 天野. アキュムレータマシン. ir. op.code. ALU. ‘ 1’. accum. pc. operand. +. idata. ddata. acout. we_. Instruction Memory. Data Memory. iadr. dadr. 状態遷移. rst_. Instruction Fetch. Execution. pc←pc + 1 ir ← idata.
E N D
計算機アーキテクチャ演習第5回Verilog特訓 慶應義塾大学 理工学部 情報工学科 天野
アキュムレータマシン ir op.code ALU ‘1’ accum pc operand + idata ddata acout we_ Instruction Memory Data Memory iadr dadr
状態遷移 rst_ Instruction Fetch Execution pc←pc+1 ir ←idata BEQ: if (accum == 0) pc← ir[3:0] BNQ: if (accum != 0) pc← ir[3:0] ST: we_ = L else: accum ← ALU出力
アキュムレータの記述(1) parameter Enable = 1’b1; parameter Disable = 1’b0; parameter Enable_ = 1’b0; parameter Disable_ = 1’b1; parameter DataBus=4; parameter InstBus=8; parameter STNUM=2; parameter IF=2’b01; parameter EX=2’b10; parameter EX_BIT=1‘b1; parameter BEQ= 4’b1010; parameter BNQ= 4’b1011; parameter ST=4’b1000;
アキュムレータの記述(2) module accum(clock, rst_, acout); input clock, rst_; output [DataBus-1:0] acout; wire [DataBus-1:0] ddata; wire [InstBus-1:0] idata; wire [DataBus-1:0] dadr; wire we; reg [DataBus-1:0] accum; // Accumulator reg [DataBus-1:0] pc;// Program Counter reg [InstBus-1:0] ir; // Instruction Register reg [STNUM-1:0] stat; // State register wire [DataBus-1:0] aluout; assign acout = accum; assign dadr = ir[3:0]; assign we = stat[EX_BIT] & (ir[7:4] == ST); ALU alu0(.A(accum), .B(ddata), .COM(ir[6:4]), .ALUOUT(aluout)); ROM16_8 imem(.AD(pc), .DOUT(idata)); RAM16_4 dmem (.CLK(clock), .WE(we), .ADDRESS(dadr), .DIN(accum), .DOUT(ddata));
アキュムレータの記述(3) always@(posedge clock) begin if(rst_ == Enable_) begin stat <= IF; pc <= 4'b0000; end else case (stat) //Case文 IF: begin ir <= idata; pc <= pc+1; stat <= EX; end EX: begin case (ir[7:4])//Case文入れ子 BEQ: if (accum == 4'b0000) pc <= ir[3:0]; BNE: if (accum != 4'b0000) pc <= ir[3:0]; default: if(ir[7]==1'b0) accum <= aluout; endcase stat <= IF; end endcase end endmodule この記述は命令により様々なレジスタを 制御している リソースシュアリングが 可能だが、やりすぎると バグの元なので注意!
演習 ir 2)ALUのコマンドに111を op.code ALU ‘1’ accum pc 111 operand 1)Operand をALUのb入力へ + idata ddata acout we_ Instruction Memory Data Memory iadr dadr • アキュムレータにSUBI命令を付け加えよ
SUBIの付加 module accum(clock, rst_, acout); input clock, rst_; output [DataBus-1:0] acout; wire [DataBus-1:0] ddata; wire [InstBus-1:0] idata,alubin; wire [DataBus-1:0] dadr; wire we; wire [2:0] alucom; reg [DataBus-1:0] accum; // Accumulator reg [DataBus-1:0] pc;// Program Counter reg [InstBus-1:0] ir; // Instruction Register reg [STNUM-1:0] stat; // State register wire [DataBus-1:0] aluout; assign acout = accum; assign dadr = ir[3:0]; assign we = stat[EX_BIT] & (ir[7:4] == ST); assign alubin = ir[7:4] == SUBI ? Ir[3:0] : ddata; assign alucom = ir[7:4] == SUBI ? 3’b111: ir[6:4] ALU alu0(.A(accum), .B(alubin), .COM(alucom), .ALUOUT(aluout)); ROM16_8 imem(.AD(pc), .DOUT(idata)); RAM16_4 dmem (.CLK(clock), .WE(we), .ADDRESS(dadr), .DIN(accum), .DOUT(ddata));
演習 • LDI #n 命令を付加せよ。この命令ではnが直接accに格納される。 • 現在の設計では、PCをインクリメントする加算器が生成される。IFステージで遊んでいるALUを利用することで、加算器を使わないでPCをインクリメントするようにデータパスを改造せよ。
演習 サイコロ • STOP入力がHレベルの時に停止し、Lレベルの時に1→2→…→6→1→…と数えるサイコロ用のカウンタをVerilog記述で設計せよ。(やり方は自由、加算器を使っても良いし使わなくても良い)
演習 Barrel Shifter • 一度に多くの桁数をシフトするハードウェアであるBarrel ShifterをVerilogのfunctionとして記述せよ(下図のように8bit左シフトとせよ) y0 y1 y2 y7 y4 y3 y5 y6 s2 0000 s1 00 s0 0 a0 a1 a2 a7 a4 a3 a5 a6