Cコード例 - 1個ずつ入力して直近N個の和を1個ずつ出力する回路
シフトレジスタ型の例として、データを1個ずつ入力して直近N個の和を1個ずつ出力する回路のCコードを示す。
◇
合成対象のCコード
/* dut.h */ #ifndef DUT_H #define DUT_H #include <ap_int.h> static const int N=10; // number of din static const int WN=4; // bit width of N typedef ap_int<8> din_t; typedef ap_int<8+WN> dout_t; void dut_hls (din_t din // (i) input data ,dout_t *dout // (o) output data ); #endif |
/* dut.cpp */ #include "dut.h" void dut_hls (din_t din // (i) input data ,dout_t *dout // (o) output data ) { #pragma HLS interface ap_ctrl_none port=return #pragma HLS interface ap_none port=din #pragma HLS interface ap_none port=dout #pragma HLS pipeline II=1 static dout_t d[N]; #pragma HLS array_patition variable=d complete #pragma HLS reset variable=d // リセット端子をつける *dout = d[N-1]; for(int i=N-1; i>0; i--) { d[i] = d[i-1] + din; } d[0] = din; } |
◇◇
Cのテストベンチ
/* main.cpp */ #include <iostream> #include "dut.h" using namespace std; /************************ * サブルーチン - 期待値比較 ************************/ void dut_golden(din_t din,dout_t dout) { static dout_t d[N]; dout_t dout_tmp; dout_tmp = d[N-1]; for(int i=N-1; i>0; i--) { d[i] = d[i-1] + din; } d[0] = din; cout << "-- din=" << din; cout << " dout= " << dout; if(dout==dout_tmp) { cout << "[PASS]" << endl; } else { cout << "[FAIL]" << endl; } } /************************ * メインルーチン ************************/ int main(int argc,char *argv[]) { din_t din; dout_t dout; for(int i=0; i<=2*N; i++) { din = (i<N)? (i+1) : 0; dut_hls(din,&dout); dut_golden(din,dout); } return 0; } |
◇◇
合成後RTLのテストベンチ
/* tb.sv */ `timescale 1ns/1ps module tb; parameter N=10; // number of din parameter WN=$clog2(N); // bit width of N reg clk; reg rst; reg[7:0] din; wire[7+WN:0] dout;
dut_hls dut (.ap_clk(clk) ,.ap_rst(rst) ,.din (din) // (i) ,.dout(dout) // (o) ); /* クロック生成 */ initial begin clk = 1'b1; forever #(5) clk = ~clk; // 10ns end /* ドライバタスク */ task din_burst (input[7:0] base // din[i]=base+i ,input int num // 連続入力数 ); begin for(int i=0; i<num; i++) begin @(posedge clk); din <= base+i; end for(int i=0; i<2*N-num; i++) begin @(posedge clk); din <= 8'd0; end end endtask /* モニタ */ always @(negedge clk) begin if(~rst) $display("--(%t) din=%h dout=%h" ,$time,din,dout); end /* シナリオ */ initial begin $timeformat(-6,3," us",10); rst = 1'b1; #(15) rst = 1'b0; din_burst(.base(8'd2),.num(1)); din_burst(.base(8'd1),.num(N)); repeat(5) @(posedge clk); $finish; end endmodule |