/* **************************** 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
// *****************************************************************************