// laplacian_filter_soft.c
// m_axi offset=slave Version
// lap_filter_axim()
// 2015/08/26 by marsee
//
#include <stdio.h>
#include <string.h>
#define HORIZONTAL_PIXEL_WIDTH 64
#define VERTICAL_PIXEL_WIDTH 48
//#define HORIZONTAL_PIXEL_WIDTH 800
//#define VERTICAL_PIXEL_WIDTH 600
#define ALL_PIXEL_VALUE (HORIZONTAL_PIXEL_WIDTH*VERTICAL_PIXEL_WIDTH)
int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2);
int conv_rgb2y(int rgb);
int lap_filter_axim(volatile int *cam_fb, volatile int *lap_fb)
{
#pragma HLS INTERFACE s_axilite port=return
#pragma HLS INTERFACE m_axi depth=3072 port=cam_fb offset=slave bundle=cam_fb
#pragma HLS INTERFACE m_axi depth=3072 port=lap_fb offset=slave bundle=lap_fb
int line_buf[3][HORIZONTAL_PIXEL_WIDTH];
int x, y;
int lap_fil_val;
int a, b;
int fl, sl, tl;
// RGB値をY(輝度成分)のみに変換し、ラプラシアンフィルタを掛けた。
for (y=0; y<VERTICAL_PIXEL_WIDTH; y++){
for (x=0; x<HORIZONTAL_PIXEL_WIDTH; x++){
if (y==0 || y==VERTICAL_PIXEL_WIDTH-1){ // 縦の境界の時の値は0とする
lap_fil_val = 0;
}else if (x==0 || x==HORIZONTAL_PIXEL_WIDTH-1){ // 横の境界の時も値は0とする
lap_fil_val = 0;
}else{
if (y == 1 && x == 1){ // 最初のラインの最初のピクセルでは2ライン分の画素を読み出す
for (a=0; a<2; a++){ // 2ライン分
for (b=0; b<HORIZONTAL_PIXEL_WIDTH; b++){ // ライン
line_buf[a][b] = cam_fb[(a*HORIZONTAL_PIXEL_WIDTH)+b];
line_buf[a][b] = conv_rgb2y(line_buf[a][b]);
}
}
}
if (x == 1) { // ラインの最初なので、2つのピクセルを読み込む
for (b=0; b<2; b++){ // ライン
line_buf[(y+1)%3][b] = cam_fb[((y+1)*HORIZONTAL_PIXEL_WIDTH)+b];
// (y+1)%3 は、使用済みのラインがに読み込む、y=2 の時 line[0], y=3の時 line[1], y=4の時 line[2]
line_buf[(y+1)%3][b] = conv_rgb2y(line_buf[(y+1)%3][b]);
}
}
// 1つのピクセルを読み込みながらラプラシアン・フィルタを実行する
line_buf[(y+1)%3][x+1] = cam_fb[((y+1)*HORIZONTAL_PIXEL_WIDTH)+(x+1)];
// (y+1)%3 は、使用済みのラインがに読み込む、y=2 の時 line[0], y=3の時 line[1], y=4の時 line[2]
line_buf[(y+1)%3][x+1] = conv_rgb2y(line_buf[(y+1)%3][x+1]);
fl = (y-1)%3; // 最初のライン, y=1 012, y=2 120, y=3 201, y=4 012
sl = y%3; // 2番めのライン
tl = (y+1)%3; // 3番目のライン
lap_fil_val = laplacian_fil(line_buf[fl][x-1], line_buf[fl][x], line_buf[fl][x+1], line_buf[sl][x-1], line_buf[sl][x], line_buf[sl][x+1], line_buf[tl][x-1], line_buf[tl][x], line_buf[tl][x+1]);
}
// ラプラシアンフィルタ・データの書き込み
lap_fb[(y*HORIZONTAL_PIXEL_WIDTH)+x] = (lap_fil_val<<16)+(lap_fil_val<<8)+lap_fil_val ;
// printf("x = %d y = %d", x, y);
}
}
return(1);
}
// RGBからYへの変換
// RGBのフォーマットは、{8'd0, R(8bits), G(8bits), B(8bits)}, 1pixel = 32bits
// 輝度信号Yのみに変換する。変換式は、Y = 0.299R + 0.587G + 0.114B
// "YUVフォーマット及び YUV<->RGB変換"を参考にした。http://vision.kuee.kyoto-u.ac.jp/~hiroaki/firewire/yuv.html
// 2013/09/27 : float を止めて、すべてint にした
int conv_rgb2y(int rgb){
int r, g, b, y_f;
int y;
b = rgb & 0xff;
g = (rgb>>8) & 0xff;
r = (rgb>>16) & 0xff;
y_f = 77*r + 150*g + 29*b; //y_f = 0.299*r + 0.587*g + 0.114*b;の係数に256倍した
y = y_f >> 8; // 256で割る
return(y);
}
// ラプラシアンフィルタ
// x0y0 x1y0 x2y0 -1 -1 -1
// x0y1 x1y1 x2y1 -1 8 -1
// x0y2 x1y2 x2y2 -1 -1 -1
int laplacian_fil(int x0y0, int x1y0, int x2y0, int x0y1, int x1y1, int x2y1, int x0y2, int x1y2, int x2y2)
{
int y;
y = -x0y0 -x1y0 -x2y0 -x0y1 +8*x1y1 -x2y1 -x0y2 -x1y2 -x2y2;
if (y<0)
y = 0;
else if (y>255)
y = 255;
return(y);
}
で検索すると、WARNING: [Labtools 27-3123] The debug hub core was not detected at User Scan Chain 1 or 3.
がヒットした。
という感じです。Vivado HLS 2015.4 を使用して、今までやってきた掛け算回路をAXI4 Lite Slaveインターフェースで実装します。
Vivado HLSでIP化を行って、Vivado 2015.4のIPIを使用してZYBOに実装します。
Vivado HLSで自動的に作製されたドライバを使用して、アプリケーションを作製し、掛け算回路を制御します。
ZYBO実機で掛け算回路を動作させます。シリアル・ターミナルで掛け算を行います。
// multi_apuint.cpp
#include <stdio.h>
#include <string.h>
#include <ap_int.h>
void multi_apuint(ap_uint<8> multi_in0, ap_uint<8> multi_in1,
ap_uint<16> *multi_out){
#pragma HLS PIPELINE
#pragma HLS INTERFACE ap_hs register port=multi_in1
#pragma HLS INTERFACE ap_hs register port=multi_in0
#pragma HLS INTERFACE ap_vld register port=multi_out
#pragma HLS INTERFACE ap_ctrl_hs port=return
*multi_out = multi_in0 * multi_in1;
}
#include <string.h>
#include <ap_int.h>
void multi_apuint(ap_uint<8> multi_in0, ap_uint<8> multi_in1,
ap_uint<16> *multi_out);
int main(){
using namespace std;
ap_uint<8> multi_in0;
ap_uint<8> multi_in1;
ap_uint<16> multi_out;
for (multi_in0=0, multi_in1=1; multi_in0<10; multi_in0++, multi_in1++){
multi_apuint(multi_in0, multi_in1, &multi_out);
cout << "multi_out = " << multi_out << endl;
if (multi_out != (multi_in0 * multi_in1))
return(1);
}
return(0);
}
// multi_test.c
// 2015/07/24 : by marsee
// multi_in0 の入力の時に999を入力すると終了する
//
#include <stdio.h>
#include "xmulti_apuint.h"
#include "xparameters.h"
#include "xil_types.h"
#include "xil_io.h"
#include "xil_exception.h"
#include "xscugic.h"
int main(){
XMulti_apuint XMluti_ap;
XMulti_apuint_Config *XMulti_apPtr;
int val;
// Look Up the device configuration
XMulti_apPtr = XMulti_apuint_LookupConfig(0);
if (!XMulti_apPtr){
fprintf(stderr, "XMulti_apuint configuration failed.\n");
return(-1);
}
// Initialize the Device
int Xlap_status = XMulti_apuint_CfgInitialize(&XMluti_ap, XMulti_apPtr);
if (Xlap_status != XST_SUCCESS){
fprintf(stderr, "Could not Initialize XMulti_apuint\n");
return(-1);
}
while(1){
printf("\n\rmulti_in0 = ");
scanf("%d", &val);
if(val == 999)
break;
XMulti_apuint_Set_multi_in0_V(&XMluti_ap, val);
printf("\n\rmulti_in1 = ");
scanf("%d", &val);
XMulti_apuint_Set_multi_in1_V(&XMluti_ap, val);
while(!XMulti_apuint_IsIdle(&XMluti_ap)) ;
XMulti_apuint_Start(&XMluti_ap);
while(!XMulti_apuint_IsDone(&XMluti_ap)) ;
printf("\n\rmulti_out = %d\n\r", (int)XMulti_apuint_Get_multi_out_V(&XMluti_ap));
}
return(0);
}
create_clock -period 2.500 -name multi_clk -waveform {0.000 1.250} ap_clk
// Readデータ処理モジュール用ステートマシン
always @(posedge clk_axi) begin
if (reset_axi)
cs_rdg <= idle_rdg;
else begin
case (cs_rdg)
idle_rdg :
if (ddr_cont_init_done)
cs_rdg <= init_full_mode;
init_full_mode : // 最初にcam_data_afifo をFULLにするステート、このステートではVGA信号は出力しないで、ひたすらcam_data_afifo がFULLになるのを待つ。
if (read_count==0)
cs_rdg <= wait_half_full;
wait_half_full : // cam_data_afifo がHALF_FULLになるまでこのステートで待機
if (vsync_axi)
cs_rdg <= frame_wait_state;
else if (wr_data_count<=AFIFO_HALF_FULL_VAL)
cs_rdg <= req_burst;
req_burst :
if (vsync_axi)
cs_rdg <= frame_wait_state;
else if (read_count==0) // データが全部来たら
cs_rdg <= wait_half_full;
frame_wait_state : // 1フレーム終了後vsync の時にWaitする
if (vsyncx_rise_pulse) // vsyncx の立ち上がり
cs_rdg <= frame_start_full;
frame_start_full : // 1フレームのスタートの時にFIFOをフルにする
if (read_count==0)
cs_rdg <= wait_half_full;
endcase
end
end
assign hv_count_enable = (cs_rdg==wait_half_full || cs_rdg==req_burst || cs_rdg==frame_wait_state || cs_rdg==frame_start_full) ? 1'b1 : 1'b0;
// h_count、v_count用にclk_axi 動作のcs_rdg の値を使用するので2回clk_disp 動作のFFでラッチする
always @(posedge clk_disp) begin
if (reset_disp) begin
hv_cnt_ena_d1 <= 1'b0;
hv_cnt_ena_d2 <= 1'b0;
end else begin
hv_cnt_ena_d1 <= hv_count_enable;
hv_cnt_ena_d2 <= hv_cnt_ena_d1;
end
end
// h_countの実装(水平カウンタ)
always @(posedge clk_disp) begin
if (reset_disp)
h_count <= 0;
else if (h_count>=(H_SUM-1)) // h_count がH_SUM-1よりも大きければ0に戻す(mod H_SUM)
h_count <= 0;
else if (hv_cnt_ena_d2) // 最初に非同期FIFOをフルにするまではカウントしない
h_count <= h_count + 1;
end
// v_countの実装(垂直カウンタ)
always @(posedge clk_disp) begin
if (reset_disp)
v_count <= 0;
else if (h_count>=(H_SUM-1)) begin // 水平カウンタがクリアされるとき
if (v_count>=(V_SUM-1)) // v_count がV_SUM-1よりも大きければ0に戻す(mode V_SUM)
v_count <= 0;
else if (hv_cnt_ena_d2) // 最初に非同期FIFOをフルにするまではカウントしない
v_count <= v_count + 1;
end
end
assign hv_count_ena_comb = (cs_rdg==wait_half_full || cs_rdg==req_burst || cs_rdg==frame_wait_state || cs_rdg==frame_start_full) ? 1'b1 : 1'b0;
always @(posedge clk_axi) begin
if (reset_axi) begin
hv_count_enable <= 1'b0;
end else begin
hv_count_enable <= hv_count_ena_comb;
end
end
Severity | ID | Description | Depth | Exception | Source (From) | Destination (To) | Category |
Critical | CDC-10 | Combinatorial logic detected before a synchronizer | 2 | Asynch Clock Groups | ZYBO_1_XGA_test_i/bitmap_disp_cntrler_axi_master_0/inst/bitmap_disp_eng_inst/cs_rdg_reg[0]/C | ZYBO_1_XGA_test_i/bitmap_disp_cntrler_axi_master_0/inst/bitmap_disp_eng_inst/hv_cnt_ena_d1_reg/D | No ASYNC_REG |
Info | CDC-6 | Multi-bit synchronized with ASYNC_REG property | 2 | Asynch Clock Groups | ZYBO_1_XGA_test_i/bitmap_disp_cntrler_axi_master_0/inst/bitmap_disp_eng_inst/bitmap_afifo_inst/U0/inst_fifo_gen/gconvfifo.rf/grf.rf/gntv_or_sync_fifo.gcx.clkx/wr_pntr_gc_reg[7:0]/C | ZYBO_1_XGA_test_i/bitmap_disp_cntrler_axi_master_0/inst/bitmap_disp_eng_inst/bitmap_afifo_inst/U0/inst_fifo_gen/gconvfifo.rf/grf.rf/gntv_or_sync_fifo.gcx.clkx/gsync_stage[1].rd_stg_inst/Q_reg_reg[7:0]/D | Safe |
Critical | CDC-10 | Combinatorial logic detected before a synchronizer | 2 | Asynch Clock Groups | ZYBO_1_XGA_test_i/bitmap_disp_cntrler_axi_master_0/inst/bitmap_disp_eng_inst/cs_rdg_reg[0]/C | ZYBO_1_XGA_test_i/bitmap_disp_cntrler_axi_master_0/inst/bitmap_disp_eng_inst/hv_cnt_ena_d1_reg/D | Unsafe |
どちらの方向のタイミングも無視するのが安全な場合 - set_clock_groups (-asynchronous)
一方向のパスを無視するのが安全な場合 - set_false_path
set_clock_groups -name pixel_clk2clk_fpga_0 -asynchronous -group [get_clocks [list [get_clocks -of_objects [get_pins ZYBO_1_XGA_test_i/bitmap_disp_cntrler_axi_master_0/inst/dvi_disp_i/BUFR_pixel_clk_io/O]]]] -group [get_clocks clk_fpga_0]
#include <string.h>
#include <ap_int.h>
void multi_apuint(ap_uint<8> multi_in0, ap_uint<8> multi_in1,
ap_uint<16> *multi_out);
int main(){
using namespace std;
ap_uint<8> multi_in0;
ap_uint<8> multi_in1;
ap_uint<16> multi_out;
for (multi_in0=0, multi_in1=1; multi_in0<10; multi_in0++, multi_in1++){
multi_apuint(multi_in0, multi_in1, &multi_out);
cout << "multi_out = " << multi_out << endl;
if (multi_out != (multi_in0 * multi_in1))
return(1);
}
return(0);
}
// display_cont.cpp
// 2015/06/03 by marsee
//
// 画面を4分割した第1象限は赤、第2象限は緑、第3象限は青、第4象限は白を表示する
//
#include <stdio.h>
#include <string.h>
#include <ap_int.h>
// SVGA 解像度
#define H_ACTIVE_VIDEO 800
#define H_FRONT_PORCH 40
#define H_SYNC_PULSE 128
#define H_BACK_PORCH 88
#define H_SUM (H_ACTIVE_VIDEO + H_FRONT_PORCH + H_SYNC_PULSE + H_BACK_PORCH)
#define V_ACTIVE_VIDEO 600
#define V_FRONT_PORCH 1
#define V_SYNC_PULSE 4
#define V_BACK_PORCH 23
#define V_SUM (V_ACTIVE_VIDEO + V_FRONT_PORCH + V_SYNC_PULSE + V_BACK_PORCH)
void display_cont_sub(ap_uint<8> *red, ap_uint<8> *green, ap_uint<8> *blue, ap_uint<1> *display_enable, ap_uint<1> *hsyncx, ap_uint<1> *vsyncx){
#pragma HLS INTERFACE ap_none register port=red
#pragma HLS INTERFACE ap_none register port=green
#pragma HLS INTERFACE ap_none register port=blue
#pragma HLS INTERFACE ap_none register port=display_enable
#pragma HLS INTERFACE ap_none register port=hsyncx
#pragma HLS INTERFACE ap_none register port=vsyncx
#pragma HLS INTERFACE ap_ctrl_hs port=return
ap_uint<16> h_count, v_count;
for (v_count=0; v_count<V_SUM; v_count++){
for (h_count=0; h_count<H_SUM; h_count++){
#pragma HLS PIPELINE rewind
if (h_count > (H_ACTIVE_VIDEO +H_FRONT_PORCH) && h_count < (H_ACTIVE_VIDEO + H_FRONT_PORCH + H_SYNC_PULSE))
*hsyncx = 0;
else
*hsyncx = 1;
if (v_count > (V_ACTIVE_VIDEO + V_FRONT_PORCH) && v_count < (V_ACTIVE_VIDEO + V_FRONT_PORCH + V_SYNC_PULSE))
*vsyncx = 0;
else
*vsyncx = 1;
if (h_count < H_ACTIVE_VIDEO && v_count < V_ACTIVE_VIDEO)
*display_enable = 1;
else
*display_enable = 0;
if (v_count < V_ACTIVE_VIDEO/2){
if (h_count < H_ACTIVE_VIDEO/2){
*red=0xff; *green=0; *blue=0;
} else if (h_count < H_ACTIVE_VIDEO){
*red=0; *green=0xff; *blue=0;
} else {
*red=0; *green=0; *blue=0;
}
} else if (v_count < V_ACTIVE_VIDEO){
if (h_count < H_ACTIVE_VIDEO/2){
*red=0; *green=0; *blue=0xff;
} else if (h_count < H_ACTIVE_VIDEO){
*red=0xff; *green=0xff; *blue=0xff;
} else {
*red=0; *green=0; *blue=0;
}
} else {
*red=0; *green=0; *blue=0;
}
}
}
}
//
// display_cont_tb.cpp
// 2015/06/03 by marsee
//
#include <stdio.h>
#include <string.h>
#include <ap_int.h>
void display_cont_sub(ap_uint<8> *red, ap_uint<8> *green, ap_uint<8> *blue, ap_uint<1> *display_enable, ap_uint<1> *hsyncx, ap_uint<1> *vsyncx);
int main(){
ap_uint<8> redb, *red;
ap_uint<8> greenb, *green;
ap_uint<8> blueb, *blue;
ap_uint<1> deb, *display_enable;
ap_uint<1> hb, *hsyncx;
ap_uint<1> vb, *vsyncx;
red = &redb;
green = &greenb;
blue = &blueb;
display_enable = &deb;
hsyncx = &hb;
vsyncx = &vb;
display_cont_sub(red, green, blue, display_enable, hsyncx, vsyncx);
return 0;
}
/*
* hdmi_in_disp.c
*
* Created on: 2015/12/15
* Author: marsee
*/
#include <stdio.h>
#include <stdlib.h>
#include "xaxivdma.h"
#include "xil_io.h"
#include "xparameters.h"
#include "sleep.h"
#define NUMBER_OF_WRITE_FRAMES 3 // Note: If not at least 3 or more, the image is not displayed in succession.
#define HORIZONTAL_PIXELS 1024
#define VERTICAL_LINES 768
#define PIXEL_NUM_OF_BYTES 4
#define FRAME_BUFFER_ADDRESS 0x10000000
static XAxiVdma_DmaSetup Vdma0_WriteCfg;
int main(){
// malloc frame buffer
// unsigned int *frame_buffer = (unsigned int *)malloc(HORIZONTAL_PIXELS * VERTICAL_LINES * PIXEL_NUM_OF_BYTES * NUMBER_OF_WRITE_FRAMES);
// AXI VDMA Initialization sequence
XAxiVdma_Config *XAxiVdma0_Config;
XAxiVdma XAxiVdma0;
int XAxiVdma0_Status;
XAxiVdma0_Config = XAxiVdma_LookupConfig(XPAR_AXI_VDMA_0_DEVICE_ID); // Look up the hardware configuration for a device instance
if (XAxiVdma0_Config == NULL){
fprintf(stderr, "No AXI VDMA found\n");
return(-1);
}
XAxiVdma0_Status = XAxiVdma_CfgInitialize(&XAxiVdma0, XAxiVdma0_Config, XAxiVdma0_Config->BaseAddress); // Initialize the driver with hardware configuration
if (XAxiVdma0_Status != XST_SUCCESS){
fprintf(stderr, "XAxiVdma_CfgInitialize() failed\n");
return(-1);
}
XAxiVdma_Reset(&XAxiVdma0, XAXIVDMA_WRITE);
while(XAxiVdma_ResetNotDone(&XAxiVdma0, XAXIVDMA_WRITE)) ;
XAxiVdma0_Status = XAxiVdma_SetFrmStore(&XAxiVdma0, NUMBER_OF_WRITE_FRAMES, XAXIVDMA_WRITE); // Set the number of frame store buffers to use.
Vdma0_WriteCfg.VertSizeInput = VERTICAL_LINES;
Vdma0_WriteCfg.HoriSizeInput = HORIZONTAL_PIXELS * PIXEL_NUM_OF_BYTES;
Vdma0_WriteCfg.Stride = HORIZONTAL_PIXELS * PIXEL_NUM_OF_BYTES; // Indicates the number of address bytes between the first pixels of each video line.
Vdma0_WriteCfg.FrameDelay = 0; // Indicates the minimum number of frame buffers the Genlock slave is to be behind the locked master. This field is only used if the channel is enabled for Genlock Slave operations. This field has no meaning in other Genlock modes.
Vdma0_WriteCfg.EnableCircularBuf = 1; // Indicates frame buffer Circular mode or frame buffer Park mode. 1 = Circular Mode Engine continuously circles through frame buffers.
Vdma0_WriteCfg.EnableSync = 0; // Enables Genlock or Dynamic Genlock Synchronization. 0 = Genlock or Dynamic Genlock Synchronization disabled.
Vdma0_WriteCfg.PointNum = 0; // No Gen-Lock
Vdma0_WriteCfg.EnableFrameCounter = 0; // Endless transfers
Vdma0_WriteCfg.FixedFrameStoreAddr = 0; // We are not doing parking
XAxiVdma0_Status = XAxiVdma_DmaConfig(&XAxiVdma0, XAXIVDMA_WRITE, &Vdma0_WriteCfg);
if (XAxiVdma0_Status != XST_SUCCESS){
fprintf(stderr, "XAxiVdma_DmaConfig() failed\n");
return(-1);
}
// Frame buffer address set
unsigned int frame_addr = (unsigned int)FRAME_BUFFER_ADDRESS;
int i;
for (i=0; i<NUMBER_OF_WRITE_FRAMES; i++){
Vdma0_WriteCfg.FrameStoreStartAddr[i] = frame_addr;
frame_addr += HORIZONTAL_PIXELS * PIXEL_NUM_OF_BYTES * VERTICAL_LINES;
}
XAxiVdma0_Status = XAxiVdma_DmaSetBufferAddr(&XAxiVdma0, XAXIVDMA_WRITE, Vdma0_WriteCfg.FrameStoreStartAddr);
if (XAxiVdma0_Status != XST_SUCCESS){
fprintf(stderr, "XAxiVdma_DmaSetBufferAddr() failed\n");
return(-1);
}
// VDMA start
XAxiVdma0_Status = XAxiVdma_DmaStart(&XAxiVdma0, XAXIVDMA_WRITE);
if (XAxiVdma0_Status != XST_SUCCESS){
fprintf(stderr, "XAxiVdma_DmaStart() failed\n");
return(-1);
}
// mt9d111_inf_axis_0, axi_iic_0, bitmap_disp_cntrler_axi_master_0
volatile unsigned int *bmdc_axi_lites;
bmdc_axi_lites = (volatile unsigned *)XPAR_BITMAP_DISP_CNTRLER_AXI_MASTER_0_BASEADDR;
bmdc_axi_lites[0] = (volatile unsigned int)FRAME_BUFFER_ADDRESS; // Bitmap Display Controller 0 start
return(0);
}
set_property IOSTANDARD LVCMOS33 [get_ports {vga_blue[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_blue[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_blue[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_blue[0]}]
set_property PACKAGE_PIN J18 [get_ports {vga_blue[3]}]
set_property PACKAGE_PIN K19 [get_ports {vga_blue[2]}]
set_property PACKAGE_PIN M20 [get_ports {vga_blue[1]}]
set_property PACKAGE_PIN P20 [get_ports {vga_blue[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_blue[4]}]
set_property PACKAGE_PIN G19 [get_ports {vga_blue[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_green[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_green[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_green[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_green[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_green[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_green[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_red[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_red[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_red[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_red[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {vga_red[0]}]
set_property PACKAGE_PIN F20 [get_ports {vga_green[5]}]
set_property PACKAGE_PIN H20 [get_ports {vga_green[4]}]
set_property PACKAGE_PIN J19 [get_ports {vga_green[3]}]
set_property PACKAGE_PIN L19 [get_ports {vga_green[2]}]
set_property PACKAGE_PIN N20 [get_ports {vga_green[1]}]
set_property PACKAGE_PIN H18 [get_ports {vga_green[0]}]
set_property PACKAGE_PIN F19 [get_ports {vga_red[4]}]
set_property PACKAGE_PIN G20 [get_ports {vga_red[3]}]
set_property PACKAGE_PIN J20 [get_ports {vga_red[2]}]
set_property PACKAGE_PIN L20 [get_ports {vga_red[1]}]
set_property PACKAGE_PIN M19 [get_ports {vga_red[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports vga_hsync]
set_property IOSTANDARD LVCMOS33 [get_ports vga_vsync]
set_property PACKAGE_PIN P19 [get_ports vga_hsync]
set_property PACKAGE_PIN R19 [get_ports vga_vsync]
set_property PACKAGE_PIN H16 [get_ports TMDS_Clk_p]
set_property PACKAGE_PIN D19 [get_ports {TMDS_Data_p[0]}]
set_property PACKAGE_PIN C20 [get_ports {TMDS_Data_p[1]}]
set_property PACKAGE_PIN B19 [get_ports {TMDS_Data_p[2]}]
set_property IOSTANDARD TMDS_33 [get_ports TMDS_Clk_p]
set_property IOSTANDARD TMDS_33 [get_ports {TMDS_Data_p[0]}]
set_property IOSTANDARD TMDS_33 [get_ports {TMDS_Data_p[1]}]
set_property IOSTANDARD TMDS_33 [get_ports {TMDS_Data_p[2]}]
set_property PACKAGE_PIN G18 [get_ports ddc_sda_io]
set_property PACKAGE_PIN G17 [get_ports ddc_scl_io]
set_property IOSTANDARD LVCMOS33 [get_ports ddc_scl_io]
set_property IOSTANDARD LVCMOS33 [get_ports ddc_sda_io]
set_property IOSTANDARD LVCMOS33 [get_ports {hdmi_hpd[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {hdmi_out_en[0]}]
set_property PACKAGE_PIN E18 [get_ports {hdmi_hpd[0]}]
set_property PACKAGE_PIN F17 [get_ports {hdmi_out_en[0]}]
set_false_path -from [get_clocks [list [get_clocks -of_objects [get_pins ZYBO_1_XGA_test_i/bitmap_disp_cntrler_axi_master_0/inst/dvi_disp_i/BUFR_pixel_clk_io/O]]]] -to [get_clocks clk_fpga_0]
set_false_path -from [get_clocks clk_fpga_0] -to [get_clocks [list [get_clocks -of_objects [get_pins ZYBO_1_XGA_test_i/bitmap_disp_cntrler_axi_master_0/inst/dvi_disp_i/BUFR_pixel_clk_io/O]]]]
// apint_test.cpp
// 2015/12/12 by marsee
//
#include <stdio.h>
#include <ap_int.h>
int apint_test(ap_uint<8> inx[2], ap_int<12> wt[2], ap_int<25> *outy){
*outy = inx[0]*wt[0] + inx[1]*wt[1];
return(0);
}
// apint_test_tb.cpp
// 2015/12/12 by marsee
//
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <ap_int.h>
#define DECIMAL_DIGITS 6 // 小数部の桁
int apint_test(ap_uint<8> inx[2], ap_int<12> wt[2], ap_int<25> *outy);
int main(){
ap_uint<8> inx[2];
ap_int<12> wt[2]; // 小数部 DECIMAL_DIGITS ビット
ap_int<25> outy; // 小数部 DECIMAL_DIGITS ビット
int outy_temp;
int retval;
inx[0] = 2;
inx[1] = 1;
wt[0] = (ap_int<12>)((float)(1.75)*(float)(pow(2,DECIMAL_DIGITS)));
wt[1] = (ap_int<12>)((float)(-2.0)*(float)(pow(2,DECIMAL_DIGITS)));
printf("wt[0] = %d\n", (int)wt[0]);
printf("wt[1] = %d\n", (int)wt[1]);
retval = apint_test(inx, wt, &outy);
printf("outy(hex) = %x\n", (int)outy);
printf("outy = %f\n", (float)outy/(float)pow(2,DECIMAL_DIGITS));
return(retval);
}
と出力されている。outy = 1.500000
と出力されている。outy = -2.500000
と出力されている。outy = -2.500000
Vivado HLS勉強会資料の最初です。
掛け算回路をC言語で書いてVivado HLSでIPにします。そのIPをVivadoでZYBO用にインプリメントして、スイッチとLEDを使って動作させます。
Vivado HLSを使う時の初めの1歩として、いかがでしょうか?
// multi_apuint.cpp
#include <ap_int.h>
void multi_apuint(ap_uint<8> multi_in0, ap_uint<8> multi_in1,
ap_uint<16> *multi_out){
*multi_out = multi_in0 * multi_in1;
}
// multi_apuint_tb.c
#include <stdio.h>
#include <string.h>
#include <ap_int.h>
int multi_apuint(ap_uint<8> multi_in0, ap_uint<8> multi_in1, ap_uint<16> *multi_out);
int main(){
using namespace std;
ap_uint<8> multi_in0;
ap_uint<8> multi_in1;
ap_uint<16> multi_out;
multi_in0 = 10;
multi_in1 = 10;
multi_apuint(multi_in0, multi_in1, &multi_out);
cout << "multi_out = " << multi_out << endl;
if (multi_out == (multi_in0*multi_in1))
return(0);
else
return(1);
}
# multi_bd_wrapper.xdc
# 2015/07/02 by marsee
#
##Switches
##IO_L19N_T3_VREF_35 sw0
set_property PACKAGE_PIN G15 [get_ports {In0_1[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {In0_1[0]}]
##IO_L24P_T3_34 sw1
set_property PACKAGE_PIN P15 [get_ports {In0_1[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {In0_1[1]}]
##IO_L4N_T0_34 sw2
set_property PACKAGE_PIN W13 [get_ports {In0[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {In0[0]}]
##IO_L9P_T1_DQS_34 sw3
set_property PACKAGE_PIN T16 [get_ports {In0[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {In0[1]}]
##LEDs
##IO_L23P_T3_35 Dout[0]
set_property PACKAGE_PIN M14 [get_ports {Dout[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Dout[0]}]
##IO_L23N_T3_35 Dout[1]
set_property PACKAGE_PIN M15 [get_ports {Dout[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Dout[1]}]
##IO_0_35 Dout[2]
set_property PACKAGE_PIN G14 [get_ports {Dout[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Dout[2]}]
##IO_L3N_T0_DQS_AD1N_35 Dout[3]
set_property PACKAGE_PIN D18 [get_ports {Dout[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {Dout[3]}]
set_switching_activity -signal_rate 1 -static_probability .99 [get_ports]
//
// lap_fil_on.c
// Created on: 2015/12/04
// Author: marsee
//
// Refered to http://japan.xilinx.com/support/documentation/sw_manuals_j/xilinx2014_4/ug902-vivado-high-level-synthesis.pdf
//
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/mman.h>
#include <fcntl.h>
#define CMA_START_ADDRESS 0x17800000
#define VIDEO_BUFFER_START_ADDRESS 0x18000000 // Limit 0x18800000, 800*600*4 = 2MBytes * 2
int main(){
int fd2, fd3, fd4;
volatile unsigned *axis_switch_0, *axis_switch_1;
volatile unsigned *lap_filter_axis_0;
int laps_cntrl;
// axis_switch_0 (UIO2)
fd2 = open("/dev/uio2", O_RDWR); // axis_switch_0 interface AXI4 Lite Slave
if (fd2 < 1){
fprintf(stderr, "/dev/uio2 (axis_switch_0) open error\n");
exit(-1);
}
axis_switch_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd2, 0);
if (!axis_switch_0){
fprintf(stderr, "axis_switch_0 mmap error\n");
exit(-1);
}
// axis_switch_1 (UIO3)
fd3 = open("/dev/uio3", O_RDWR); // axis_switch_1 interface AXI4 Lite Slave
if (fd3 < 1){
fprintf(stderr, "/dev/uio3 (axis_switch_1) open error\n");
exit(-1);
}
axis_switch_1 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd3, 0);
if (!axis_switch_1){
fprintf(stderr, "axis_switch_1 mmap error\n");
exit(-1);
}
// lap_filter_axis_0 (UIO4)
fd4 = open("/dev/uio4", O_RDWR); // lap_filter_axis_0 interface AXI4 Lite Slave
if (fd4 < 1){
fprintf(stderr, "/dev/uio4 (lap_filter_axis_0) open error\n");
exit(-1);
}
lap_filter_axis_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd4, 0);
if (!lap_filter_axis_0){
fprintf(stderr, "lap_filter_axis_0 mmap error\n");
exit(-1);
}
// axis_switch_1, 1to2 ,Select M01_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
axis_switch_1[16] = 0x80000000; // 0x40 = 0x80000000; disable
axis_switch_1[17] = 0; // 0x44 = 0;
axis_switch_1[0] = 0x2; // 0x0 = 2; Commit registers
// laplacian filter AXIS Start
laps_cntrl = lap_filter_axis_0[0] & 0x80; // Auto Restart bit
lap_filter_axis_0[0] = laps_cntrl | 0x01; // Start bit set
lap_filter_axis_0[0] = 0x80; // Auto Restart bit set
// axis_switch_0, 2to1, Select S01_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
axis_switch_0[16] = 0x1; // 0x40 = 0x1;
axis_switch_0[0] = 0x2; // 0x0 = 2; Commit registers
munmap((void *)axis_switch_0, 0x10000);
munmap((void *)axis_switch_1, 0x10000);
munmap((void *)lap_filter_axis_0, 0x10000);
return(0);
}
//
// cam_return.c
// Created on: 2014/11/22
// Author: Masaaki
//
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/mman.h>
#include <fcntl.h>
int main(){
int fd2, fd3, fd4;
volatile unsigned *axis_switch_0, *axis_switch_1;
volatile unsigned *lap_filter_axis_0;
// axis_switch_0 (UIO2)
fd2 = open("/dev/uio2", O_RDWR); // axis_switch_0 interface AXI4 Lite Slave
if (fd2 < 1){
fprintf(stderr, "/dev/uio2 (axis_switch_0) open error\n");
exit(-1);
}
axis_switch_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd2, 0);
if (!axis_switch_0){
fprintf(stderr, "axis_switch_0 mmap error\n");
exit(-1);
}
// axis_switch_1 (UIO3)
fd3 = open("/dev/uio3", O_RDWR); // axis_switch_1 interface AXI4 Lite Slave
if (fd3 < 1){
fprintf(stderr, "/dev/uio3 (axis_switch_1) open error\n");
exit(-1);
}
axis_switch_1 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd3, 0);
if (!axis_switch_1){
fprintf(stderr, "axis_switch_1 mmap error\n");
exit(-1);
}
// lap_filter_axis_0 (UIO4)
fd4 = open("/dev/uio4", O_RDWR); // lap_filter_axis_0 interface AXI4 Lite Slave
if (fd4 < 1){
fprintf(stderr, "/dev/uio4 (lap_filter_axis_0) open error\n");
exit(-1);
}
lap_filter_axis_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd4, 0);
if (!lap_filter_axis_0){
fprintf(stderr, "lap_filter_axis_0 mmap error\n");
exit(-1);
}
// axis_switch_1, 1to2 ,Select M01_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
axis_switch_1[16] = 0; // 0x44 = 0;
axis_switch_1[17] = 0x80000000; // 0x40 = 0x80000000; disable
axis_switch_1[0] = 0x2; // 0x0 = 2; Commit registers
// laplacian filter AXIS Start
lap_filter_axis_0[0] = 0x00; // Auto Restart Disable
// axis_switch_0, 2to1, Select S01_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
axis_switch_0[16] = 0x0; // 0x40 = 0x0;
axis_switch_0[0] = 0x2; // 0x0 = 2; Commit registers
munmap((void *)axis_switch_0, 0x10000);
munmap((void *)axis_switch_1, 0x10000);
munmap((void *)lap_filter_axis_0, 0x10000);
}
// marsee_example2.c
// 2015/12/06 by marsee
// 掛け算サンプル
//
int marsee_example1(int multi_in0, int multi_in1, int *multi_out){
*multi_out = multi_in0 * multi_in1;
return 0;
}
// ==============================================================
// RTL generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC
// Version: 2015.4
// Copyright (C) 2015 Xilinx Inc. All rights reserved.
//
// ===========================================================
`timescale 1 ns / 1 ps
(* CORE_GENERATION_INFO="marsee_example1,hls_ip_2015_4,{HLS_INPUT_TYPE=c,HLS_INPUT_FLOAT=0,HLS_INPUT_FIXED=0,HLS_INPUT_PART=xc7z010clg400-1,HLS_INPUT_CLOCK=10.000000,HLS_INPUT_ARCH=others,HLS_SYN_CLOCK=6.080000,HLS_SYN_LAT=5,HLS_SYN_TPT=none,HLS_SYN_MEM=0,HLS_SYN_DSP=4,HLS_SYN_FF=6,HLS_SYN_LUT=1}" *)
module marsee_example1 (
ap_clk,
ap_rst,
ap_start,
ap_done,
ap_idle,
ap_ready,
multi_in0,
multi_in1,
multi_out,
multi_out_ap_vld,
ap_return
);
parameter ap_const_logic_1 = 1'b1;parameter ap_const_logic_0 = 1'b0;
parameter ap_ST_st1_fsm_0 = 6'b1;parameter ap_ST_st2_fsm_1 = 6'b10;
parameter ap_ST_st3_fsm_2 = 6'b100;parameter ap_ST_st4_fsm_3 = 6'b1000;
parameter ap_ST_st5_fsm_4 = 6'b10000;parameter ap_ST_st6_fsm_5 = 6'b100000;
parameter ap_const_lv32_0 = 32'b00000000000000000000000000000000;parameter ap_const_lv1_1 = 1'b1;
parameter ap_const_lv32_5 = 32'b101;parameter ap_true = 1'b1;
input ap_clk;
input ap_rst;
input ap_start;
output ap_done;
output ap_idle;
output ap_ready;
input [31:0] multi_in0;
input [31:0] multi_in1;
output [31:0] multi_out;
output multi_out_ap_vld;
output [31:0] ap_return;
// marsee_example_tb.c
// 2015/12/06 by marsee
//
#include <stdio.h>
#include <stdlib.h>
int marsee_example1(int multi_in0, int multi_in1, int *multi_out);
int main(){
int multi_in0, multi_in1, multi_out;
int ret_val;
multi_in0 = 2; multi_in1 = 3;
ret_val = marsee_example1(multi_in0, multi_in1, &multi_out);
printf("multi_out = %d\n", multi_out);
return(ret_val);
}
で動作しなかった。/dev/uio6 (bitmap_disp_cntrler_axi_master_0) open error
//
// cam_disp_vdma.c
// Created on: 2015/12/03
// Author: marsee
//
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sys/mman.h>
#include <fcntl.h>
#define CMA_START_ADDRESS 0x17800000
#define VIDEO_BUFFER_START_ADDRESS 0x18000000 // Limit 0x18800000, 800*600*4 = 2MBytes * 2
#define NUMBER_OF_WRITE_FRAMES 3 // Note: If not at least 3 or more, the image is not displayed in succession.
#define HORIZONTAL_PIXEL 800
#define ALL_CHAR_OF_1LINE (HORIZONTAL_PIXEL/8)
#define VERTICAL_PIXEL 600
#define ALL_CHAR_OF_ROW (VERTICAL_PIXEL/8)
#define ALL_DISP_ADDRESS (HORIZONTAL_PIXEL*VERTICAL_PIXEL*4)
#define ALL_DISP_CHARACTOR HORIZONTAL_PIXEL*VERTICAL_PIXEL
void cam_i2c_init(volatile unsigned *mt9d111_axi_iic) {
mt9d111_axi_iic[64] = 0x2; // reset tx fifo ,address is 0x100, i2c_control_reg
mt9d111_axi_iic[64] = 0x1; // enable i2c
}
void cam_i2x_write_sync(void) {
// unsigned c;
// c = *cam_i2c_rx_fifo;
// while ((c & 0x84) != 0x80)
// c = *cam_i2c_rx_fifo; // No Bus Busy and TX_FIFO_Empty = 1
usleep(1000);
}
void cam_i2c_write(volatile unsigned *mt9d111_axi_iic, unsigned int device_addr, unsigned int write_addr, unsigned int write_data){
mt9d111_axi_iic[66] = 0x100 | (device_addr & 0xfe); // Slave IIC Write Address, address is 0x108, i2c_tx_fifo
mt9d111_axi_iic[66] = write_addr;
mt9d111_axi_iic[66] = (write_data >> 8)|0xff; // first data
mt9d111_axi_iic[66] = 0x200 | (write_data & 0xff); // second data
cam_i2x_write_sync();
}
int main()
{
int i, j, k;
int fd0, fd1, fd2, fd3, fd4, fd5, fd6, fd7, fd8, fd9;
volatile unsigned *bmdc_axi_lites0, *bmdc_axi_lites1;
volatile unsigned *axi_vdma_0;
volatile unsigned *axis_switch_0, *axis_switch_1;
volatile unsigned *mt9d111_inf_axis_0;
volatile unsigned *mt9d111_axi_iic;
volatile unsigned *axi_gpio_0;
volatile unsigned *frame_buffer_bmdc;
// Bitmap Display Controller 0 AXI4 Lite Slave (UIO6)
fd6 = open("/dev/uio6", O_RDWR); // bitmap_display_controller 0 axi4 lite
if (fd6 < 1){
fprintf(stderr, "/dev/uio6 (bitmap_disp_cntrler_axi_master_0) open error\n");
exit(-1);
}
bmdc_axi_lites0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd6, 0);
if (!bmdc_axi_lites0){
fprintf(stderr, "bmdc_axi_lites0 mmap error\n");
exit(-1);
}
bmdc_axi_lites0[0] = VIDEO_BUFFER_START_ADDRESS; // Bitmap Display 1 Controller start
// Bitmap Display Controller 1 AXI4 Lite Slave (UIO7)
fd7 = open("/dev/uio7", O_RDWR); // bitmap_display_controller axi4 lite
if (fd7 < 1){
fprintf(stderr, "/dev/uio7 (bitmap_disp_cntrler_axi_master_0) open error\n");
exit(-1);
}
bmdc_axi_lites1 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd7, 0);
if (!bmdc_axi_lites1){
fprintf(stderr, "bmdc_axi_lites1 mmap error\n");
exit(-1);
}
bmdc_axi_lites1[0] = VIDEO_BUFFER_START_ADDRESS; // Bitmap Display Controller start
// axi_vdma_0 (UIO1)
fd1 = open("/dev/uio1", O_RDWR); // axi_vdma_0 interface AXI4 Lite Slave
if (fd1 < 1){
fprintf(stderr, "/dev/uio1 (axi_vdma_0) open error\n");
exit(-1);
}
axi_vdma_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd1, 0);
if (!axi_vdma_0){
fprintf(stderr, "axi_vdma_0 mmap error\n");
exit(-1);
}
// mt9d111 i2c AXI4 Lite Slave (UIO0)
fd0 = open("/dev/uio0", O_RDWR); // mt9d111 i2c AXI4 Lite Slave
if (fd0 < 1){
fprintf(stderr, "/dev/uio0 (mt9d111_axi_iic) open error\n");
exit(-1);
}
mt9d111_axi_iic = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd0, 0);
if (!mt9d111_axi_iic){
fprintf(stderr, "mt9d111_axi_iic mmap error\n");
exit(-1);
}
// mt9d111 inf axis AXI4 Lite Slave (UIO5)
fd5 = open("/dev/uio5", O_RDWR); // mt9d111 inf axis AXI4 Lite Slave
if (fd5 < 1){
fprintf(stderr, "/dev/uio5 (mt9d111_inf_axis_0) open error\n");
exit(-1);
}
mt9d111_inf_axis_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd5, 0);
if (!mt9d111_inf_axis_0){
fprintf(stderr, "mt9d111_inf_axis_0 mmap error\n");
exit(-1);
}
// axis_switch_0 (UIO2)
fd2 = open("/dev/uio2", O_RDWR); // axis_switch_0 interface AXI4 Lite Slave
if (fd2 < 1){
fprintf(stderr, "/dev/uio2 (axis_switch_0) open error\n");
exit(-1);
}
axis_switch_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd2, 0);
if (!axis_switch_0){
fprintf(stderr, "axis_switch_0 mmap error\n");
exit(-1);
}
// axis_switch_1 (UIO3)
fd3 = open("/dev/uio3", O_RDWR); // axis_switch_1 interface AXI4 Lite Slave
if (fd3 < 1){
fprintf(stderr, "/dev/uio3 (axis_switch_1) open error\n");
exit(-1);
}
axis_switch_1 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd3, 0);
if (!axis_switch_1){
fprintf(stderr, "axis_switch_1 mmap error\n");
exit(-1);
}
// axi_gpio_0 (UIO8)
fd8 = open("/dev/uio8", O_RDWR); // axi_gpio_0 interface AXI4 Lite Slave
if (fd8 < 1){
fprintf(stderr, "/dev/uio8 (axi_gpio_0) open error\n");
exit(-1);
}
axi_gpio_0 = (volatile unsigned *)mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, fd8, 0);
if (!axi_gpio_0){
fprintf(stderr, "axi_gpio_8 mmap error\n");
exit(-1);
}
// frame_buffer_bmdc UIO9
fd9 = open("/dev/uio9", O_RDWR); // frame_buffer_bmdc
if (fd3 < 1){
fprintf(stderr, "/dev/uio9 (frame_buffer_bmdc) open error\n");
exit(-1);
}
frame_buffer_bmdc = (volatile unsigned *)mmap(NULL, 0x1000000, PROT_READ|PROT_WRITE, MAP_SHARED, fd9, 0);
if (!frame_buffer_bmdc){
fprintf(stderr, "frame_buffer_bmdc mmap error\n");
exit(-1);
}
// axis_switch_1, 1to2 ,Select M00_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
axis_switch_1[16] = 0x0; // 0x40 = 0
axis_switch_1[17] = 0x80000000; // 0x44 = 0x80000000, disable
axis_switch_1[0] = 0x2; // Comit registers
// axis_switch_0, 2to1, Select S00_AXIS
// Refer to http://marsee101.blog19.fc2.com/blog-entry-3177.html
axis_switch_0[16] = 0x0; // 0x40 = 0;
axis_switch_0[0] = 0x2; // Comit registers
// AXI VDMA Initialization sequence
axi_vdma_0[12] = 0x4; // S2MM_VDMACR (S2MM VDMA Control Register Offset 30h) is 0x4
while ((axi_vdma_0[12] & 0x4) == 0x4) ; // Reset is progress
axi_vdma_0[12] = 0x4; // S2MM_VDMACR (S2MM VDMA Control Register Offset 30h) is 0x4
while ((axi_vdma_0[12] & 0x4) == 0x4) ; // Reset is progress
axi_vdma_0[18] = 0x3; // S2MM_FRMSTORE (0x48) register
axi_vdma_0[12] = 0x00010002; // S2MM_VDMACR(IRQFrameCount = 0x1, Circular_Park = 1)
axi_vdma_0[41] = 0xc80; // S2MM Horizontal Size Register(S2MM_HSIZE)0xc80 = 3200dec = 800 x 4
axi_vdma_0[42] = 0xc80; // S2MM Frame Delay and Stride Register(S2MM_FRMDLY_STRIDE)0xc80 = 3200dec = 800 x 4
axi_vdma_0[43] = VIDEO_BUFFER_START_ADDRESS; // S2MM Start Address (1 to 16) Start Address 1
axi_vdma_0[44] = VIDEO_BUFFER_START_ADDRESS+ALL_DISP_ADDRESS; // S2MM Start Address (1 to 16) Start Address 2
axi_vdma_0[45] = VIDEO_BUFFER_START_ADDRESS+2*ALL_DISP_ADDRESS; // S2MM Start Address (1 to 16) Start Address 3
axi_vdma_0[12] = 0x00010003; // S2MM_VDMACR(IRQFrameCount = 0x1, Circular_Park = 1, Run/stop = 1)
while((axi_vdma_0[13] & 0x1) == 0x1) ; // Halt? (S2MM_VDMASR 0x34)
axi_vdma_0[40] = 0x258; // S2MM Vertical Size (S2MM_VSIZE Offset 0xA0) 0x258 = 600dec
bmdc_axi_lites0[0] = (volatile unsigned int)VIDEO_BUFFER_START_ADDRESS; // Bitmap Display Controller 0 start
bmdc_axi_lites1[0] = (volatile unsigned int)VIDEO_BUFFER_START_ADDRESS; // Bitmap Display Controller 1 start
mt9d111_inf_axis_0[0] = (volatile unsigned int)VIDEO_BUFFER_START_ADDRESS; // Camera Interface start (Address is dummy)
// CMOS Camera initialize, MT9D111
cam_i2c_init(mt9d111_axi_iic);
cam_i2c_write(mt9d111_axi_iic, 0xba, 0xf0, 0x1); // Changed regster map to IFP page 1
cam_i2c_write(mt9d111_axi_iic, 0xba, 0x97, 0x20); // RGB Mode, RGB565
mt9d111_inf_axis_0[1] = 0;
munmap((void *)bmdc_axi_lites0, 0x10000);
munmap((void *)bmdc_axi_lites1, 0x10000);
munmap((void *)axi_vdma_0, 0x10000);
munmap((void *)mt9d111_inf_axis_0, 0x10000);
munmap((void *)mt9d111_axi_iic, 0x10000);
munmap((void *)axis_switch_0, 0x10000);
munmap((void *)axis_switch_1, 0x10000);
munmap((void *)axi_gpio_0, 0x10000);
munmap((void *)frame_buffer_bmdc, 0x1000000);
return(0);
}
日 | 月 | 火 | 水 | 木 | 金 | 土 |
---|---|---|---|---|---|---|
- | - | 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 | - | - |