論理回路デザイン |
|
/* **************************** MODULE PREAMBLE ******************************** Copyright (c) 2011, ArchiTek This document constitutes confidential and proprietary information of ArchiTek. All rights reserved. // このコードと前ページのコード、およびfifoのコードをコンパイルすれば結果が出る // なお、命令列はオーバーラップを考慮しないものである */ // ***************************** MODULE HEADER ********************************* `timescale 1ps / 1ps module test; // ************************ PARAMETER DECLARATIONS ***************************** parameter D = 1; parameter DCLK = 5000; parameter DCLK2 = DCLK/2; // ************************** LOCAL DECLARATIONS ******************************* reg clk; reg reset_n; // ****************************** MODULE BODY ********************************** // ----------------------------------------------------------------------------- initial begin clk=0; forever begin #(DCLK2) clk=~clk; end end // ----------------------------------------------------------------------------- initial begin reset_n=0; #D reset_n=0; #(DCLK*3.5) reset_n=1; end // ----------------------------------------------------------------------------- top top_0 ( clk, reset_n ); // ************************** FUNCTIONS and TASKS ****************************** endmodule // ***************************************************************************** /* **************************** MODULE PREAMBLE ******************************** Copyright (c) 2011, ArchiTek This document constitutes confidential and proprietary information of ArchiTek. All rights reserved. */ // ***************************** MODULE HEADER ********************************* module top ( clk, reset_n ); // ***************************** I/O DECLARATIONS ****************************** input clk; input reset_n; // ************************** LOCAL DECLARATIONS ******************************* reg iVld; wire iStall; wire iOut; wire [11:0] iMCode; wire [15:0] iMA; wire [15:0] iMB; wire [11:0] iACode; wire [15:0] iAA; wire [15:0] iAB; wire oVld; reg oStall; wire [15:0] oMY; wire [15:0] oAY; reg [7:0] oCnt; reg [1:0] rst; reg reset; // ******************************** MODULE BODY ******************************** // ----------------------------------------------------------------------------- // Pipeline drive always @(posedge clk) if (reset) iVld <= #1 1'b0; else if (!iStall) iVld <= #1 $random; always @(posedge clk) if (reset) oStall <= #1 1'b0; else oStall <= #1 $random; always @(posedge clk) if (reset) oCnt <= #1 8'd0; else oCnt <= #1 oCnt + (oVld & !oStall); // ----------------------------------------------------------------------------- // Clock & Reset // Generate a synchronized reset always @(posedge clk or negedge reset_n) if (!reset_n) rst <= #1 2'b11; else rst <= #1 {rst[0], 1'b0}; always @(posedge clk or negedge reset_n) if (!reset_n) reset <= #1 1'b1; else reset <= #1 rst[1]; // ----------------------------------------------------------------------------- // FPU // 22個のレジスタを持つFPUとして設定 fpu #(2) fpu_0 ( .iVld (iVld), .iStall (iStall), .iOut (iOut), .iMCode (iMCode), .iMA (iMA), .iMB (iMB), .iACode (iACode), .iAA (iAA), .iAB (iAB), .oVld (oVld), .oStall (oStall), .oMY (oMY), .oAY (oAY), .reset (reset), .clk (clk) ); // ----------------------------------------------------------------------------- // Sequencer ts ts_0 ( .iVld (iVld), .iStall (iStall), .iOut (iOut), .iMCode (iMCode), .iMA (iMA), .iMB (iMB), .iACode (iACode), .iAA (iAA), .iAB (iAB), .oVld (oVld), .oStall (oStall), .oMY (oMY), .oAY (oAY), .reset (reset), .clk (clk) ); // **************************** FUNCTIONS and TASKS **************************** endmodule // ***************************************************************************** /* **************************** MODULE PREAMBLE ******************************** Copyright (c) 2011, ArchiTek This document constitutes confidential and proprietary information of ArchiTek. All rights reserved. */ // ***************************** MODULE HEADER ********************************* module ts ( iVld, iStall, iOut, iMCode, iMA, iMB, iACode, iAA, iAB, oVld, oStall, oMY, oAY, clk, reset ); // ***************************** I/O DECLARATIONS ****************************** input iVld; input iStall; output iOut; output [11:0] iMCode; output [15:0] iMA; output [15:0] iMB; output [11:0] iACode; output [15:0] iAA; output [15:0] iAB; input oVld; input oStall; input [15:0] oMY; input [15:0] oAY; input clk; input reset; // ************************** LOCAL DECLARATIONS ******************************* reg iOut; reg [11:0] iMCode; reg [15:0] iMA; reg [15:0] iMB; reg [11:0] iACode; reg [15:0] iAA; reg [15:0] iAB; reg [15:0] expM; reg [15:0] expA; wire [15:0] resultM; wire [15:0] resultA; reg [9:0] iSc; reg [9:0] oSc; reg simEnd; wire doEnd; wire errY; wire iAlloc = iVld & !iStall; wire oAlloc = oVld & !oStall; // ******************************** MODULE BODY ******************************** // Timing synchronizer for expectation // iOutがアサートされるもののみFIFOに入れる、乗算器の結果は見なくてもいいが、参考のため記述 fifo #(33, 8) fifo_0 ( .iVld (iAlloc & iOut), .iStall (), .iData ({simEnd, expM, expA}), .oVld (), .oStall (!oAlloc), .oData ({doEnd, resultM, resultA}), .reset (reset), .clk (clk) ); always @(posedge clk) if (oAlloc) begin case (errY) 1'b0: $display(" OK : oMY=%4h\texpM=%4h\t\t oAY=%4h\texpA=%4h\t@%d", oMY, resultM, oAY, resultA, oSc); 1'b1: $display(" NG : oMY=%4h\texpM=%4h\t\t oAY=%4h\texpA=%4h\t@%d", oMY, resultM, oAY, resultA, oSc); endcase if (doEnd) $finish; end assign errY = (resultM != oMY) | (resultA != oAY); // Test in counter always @(posedge clk) if (reset) iSc <= #1 10'd0; else iSc <= #1 iSc + iAlloc; // Test out counter always @(posedge clk) if (reset) oSc <= #1 10'd0; else oSc <= #1 oSc + oAlloc; // Test sequence // iScをPCとして、Instructionと演算器の入力値を生成する always @( iSc ) begin simEnd = 1'b0; case (iSc) // Option___Imm_Alt_Reg#___Imm_Alt_Reg#___WE_Reg# // Result(R0a) <- (A0B0+C0C0)D0+(A1B1+C1C1)D1 // Reg #のフィールド長はレジスタ数が4なので2 // ここでは減算を使用しないので、Codeの先頭は常に0 // NOPはWEを0にするだけで十分だが、全フィールド0にしている 10'd0: begin iOut = 1'b0; // 2.5 x 0.375 -> R0m iMCode = 12'b0___10_00___10_00___1_00; iMA = 16'h4100; iMB = 16'h3600; // NOP iACode = 12'b0___00_00___00_00___0_00; iAA = 16'h0000; iAB = 16'h0000; expM = 16'h0000; expA = 16'h0000; end 10'd1: begin iOut = 1'b0; // 1.5 x 1.5 -> R1m iMCode = 12'b0___10_00___10_00___1_01; iMA = 16'h3e00; iMB = 16'h3e00; // NOP iACode = 12'b0___00_00___00_00___0_00; iAA = 16'h0000; iAB = 16'h0000; expM = 16'h0000; expA = 16'h0000; end 10'd2: begin iOut = 1'b0; // 0.625 x 0.5 -> R0m iMCode = 12'b0___10_00___10_00___1_00; iMA = 16'h3900; iMB = 16'h3800; // NOP iACode = 12'b0___00_00___00_00___0_00; iAA = 16'h0000; iAB = 16'h0000; expM = 16'h0000; expA = 16'h0000; end 10'd3: begin iOut = 1'b0; // 1.0 x 1.0 -> R1m iMCode = 12'b0___10_00___10_00___1_01; iMA = 16'h3c00; iMB = 16'h3c00; // R0m(2.5x0.375) + R1m(1.5x1.5) -> R0a iACode = 12'b0___01_00___01_01___1_00; iAA = 16'h0000; iAB = 16'h0000; expM = 16'h0000; expA = 16'h0000; end 10'd4: begin iOut = 1'b0; // NOP iMCode = 12'b0___00_00___00_00___0_00; iMA = 16'h0000; iMB = 16'h0000; // NOP iACode = 12'b0___00_00___00_00___0_00; iAA = 16'h0000; iAB = 16'h0000; expM = 16'h0000; expA = 16'h0000; end 10'd5: begin iOut = 1'b0; // 0.75 x R0a(2.5x0.375+1.5x1.5) -> R0m iMCode = 12'b0___10_00___01_00___1_00; iMA = 16'h3a00; iMB = 16'h0000; // R0m(0.625x0.5) + R1m(1.0x1.0) -> R0a iACode = 12'b0___01_00___01_01___1_00; iAA = 16'h0000; iAB = 16'h0000; expM = 16'h0000; expA = 16'h0000; end 10'd6: begin iOut = 1'b0; // NOP iMCode = 12'b0___00_00___00_00___0_00; iMA = 16'h0000; iMB = 16'h0000; // NOP iACode = 12'b0___00_00___00_00___0_00; iAA = 16'h0000; iAB = 16'h0000; expM = 16'h0000; expA = 16'h0000; end 10'd7: begin iOut = 1'b0; // 0.125 x R0a(0.625x0.5+1.0x1.0) -> R1m iMCode = 12'b0___10_00___01_00___1_01; iMA = 16'h3000; iMB = 16'h0000; // NOP iACode = 12'b0___00_00___00_00___0_00; iAA = 16'h0000; iAB = 16'h0000; expM = 16'h0000; expA = 16'h0000; end 10'd8: begin iOut = 1'b0; // NOP iMCode = 12'b0___00_00___00_00___0_00; iMA = 16'h0000; iMB = 16'h0000; // NOP iACode = 12'b0___00_00___00_00___0_00; iAA = 16'h0000; iAB = 16'h0000; expM = 16'h0000; expA = 16'h0000; end 10'd9: begin iOut = 1'b1; // NOP iMCode = 12'b0___00_00___00_00___0_00; iMA = 16'h0000; iMB = 16'h0000; // R0m(0.75x(2.5x0.375+1.5x1.5)) + // R1m(0.125x(0.625x0.5+1.0x1.0)) iACode = 12'b0___01_00___01_01___1_00; iAA = 16'h0000; iAB = 16'h0000; expM = 16'h40c8; expA = 16'h411c; // この値が最終的に出れば結果OK // Simulation Terminate simEnd = 1'b1; end endcase end // **************************** FUNCTIONS and TASKS **************************** endmodule // *****************************************************************************
回路デザイン > 設計例 [浮動小数点] > 応用FPUその2 このページのTOP ▲