Cコード例 - N個を1回入力して和を1回出力する回路
パイプライン型トップ階層の例として、配列din[N]をパラレルポートとして入力して和を出力する回路の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[N] // (i) input data ,dout_t *dout // (o) output data ); #endif |
/* dut.cpp */ #include "dut.h" void dut_hls (din_t din[N] // (i) input data ,dout_t *dout // (o) output data ) { #pragma HLS interface ap_ctrl_none port=return #pragma HLS interface ap_hs port=din #pragme HLS aggregate variable=din compact=bit #pragma HLS array_reshape variable=din complete #pragma HLS interface ap_hs register port=dout #pragma HLS pipeline II=1 style=flp dout_t acc = 0; for(int i=0; i<N; i++) { acc += din[i]; } *dout = acc; } |
◇◇
Cのテストベンチ
/* main.cpp */ #include <iostream> #include "dut.h" using namespace std; /************************ * サブルーチン - 期待値比較 ************************/ void dut_golden(din_t din[N],dout_t dout) { int acc = 0; for(int i=0; i<N; i++) { acc += din[i]; } cout << "-- dout= " << dout; if(dout==acc) { cout << "[PASS]" << endl; } else { cout << "[FAIL]" << endl; } } /************************ * メインルーチン ************************/ int main(int argc,char *argv[]) { din_t din[N]; dout_t dout;
for(int i=0; i<N; i++) { din[i] = i+1; } 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 din_vld = 1'b0; reg[N-1:0][7:0] din; wire[7+WN:0] dout;
dut_hls dut (.ap_clk(clk) ,.ap_rst(rst) ,.din_ap_ack (din_ack) // (o) ,.din_ap_vld (din_vld) // (i) ,.din (din) // (i) ,.dout_ap_ack (1'b1) // (i) ,.dout_ap_vld (dout_vld) // (o) ,.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 repeat(num) @(posedge clk) begin din_vld <= 1'b1; for(int i=0; i<N; i++) din[i] <= base + i; base = base + 1'b1; end @(posedge clk); din_vld <= 1'b0; din <= 'bx; end endtask /* モニタ */ always @(negedge clk) begin if(~rst) $display("--(%t) din_vld=%b din=%h dout_vld=%b dout=%h" ,$time,din_vld,din,dout_vld,dout); end /* シナリオ */ initial begin $timeformat(-6,3," us",10); rst = 1'b1; #(15) rst = 1'b0; din_burst(.base(8'd1),.num(1)); // 1連続入力 din_burst(.base(8'd2),.num(2)); // 2連続入力 repeat(5) @(posedge clk); $finish; end endmodule |