此项目一共分为摄像头配置模块,图像采集模块,异步FIFO控制模块,SDRAM控制模块,SDRAM端口模块,VGA显示模块。

摄像头配置模块

直接采用IIC接口对摄像头进行配置:模块分化:IIC端口模块,IIC控制模块,和LUT查找表模块;配置图像像素输出为1280*720

摄像头配置参数

//涉嫌头参数配置-LUT模块
module  lut_da(input                clk         ,input              rst_n       ,input              redy        , //反馈信号,1可以发数据,0 不能读写output  reg         data_en     ,  output   [24:0]      data_out    ,output                 config_done       //1代表配置完成
);
parameter       RW_CTRL=1'b0;  //1代表写模式+读模式  ;0代表只写localparam         WAIT_TIME =1000_000,//上电等待时间MAX       =253-2       ,WAIT    =3'b001,WRITE     =3'b010,IDLE      =3'b100;reg [19:0]      cnt  ;
wire            add_cnt ;
wire            end_cnt ;reg  [24:0]    lut_data;
reg             cnt_flag;reg [2:0]          state;
reg [2:0]       state_next;
wire            wait_write  ;
wire            write_idle  ;always@(posedge clk or negedge rst_n)  beginif(!rst_n)  beginstate<=WAIT; endelse     beginstate<=state_next;end
end
always @(*)begin case(state)WAIT :beginif(wait_write)  beginstate_next=WRITE;endelse beginstate_next=WAIT;endendWRITE:beginif(write_idle)  beginstate_next=IDLE;endelse beginstate_next=WRITE;endendIDLE :beginstate_next=IDLE;enddefault:state=WAIT;endcase
end
assign  wait_write=state==WAIT && end_cnt;
assign  write_idle=state==WRITE&& end_cnt;always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt <= 0;end else if(add_cnt)begin if(end_cnt)begin cnt <= 0;endelse begin cnt <= cnt + 1'b1;end end
end
assign add_cnt = state==WAIT|| (state==WRITE&&cnt_flag);
assign end_cnt = add_cnt && cnt==(  (state==WAIT) ? (WAIT_TIME-1 ): (MAX+1) ) ;
//data_en
always @(posedge clk or negedge rst_n)begin if(!rst_n)begindata_en <= 0;end else  if( data_en==1 && state==WRITE   ) begin data_en <= 0; endelse if( state==WRITE  && redy==1 )begin   //redy==1模块空闲中,可以读写操作data_en<=1;end
end
assign  config_done= state==IDLE;
assign data_out= (state==WRITE) ? lut_data : 1'b0;
always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt_flag <= 0;end else if(data_en)begin cnt_flag<=1'b1;end else begin cnt_flag<=0;end
end
//lut_data   always@(*)begincase( cnt )                //2个字节地址,一个字节数据//15fps VGA YUV output// 24MHz input clock, 24MHz PCLK0  :     lut_data   =  {RW_CTRL,24'h3103_11}; // system clock from pad, bit[1]1  :     lut_data   =  {RW_CTRL,24'h3008_82}; // software reset, bit[7]2  :        lut_data   =  {RW_CTRL,24'h3008_42}; // software power down, bit[6]3  :       lut_data   =  {RW_CTRL,24'h3103_03}; // system clock from PLL, bit[1]4  :     lut_data   =  {RW_CTRL,24'h3017_ff}; // FREX, Vsync, HREF, PCLK, D[9:6] output enable5  :     lut_data   =  {RW_CTRL,24'h3018_ff}; // D[5:0], GPIO[1:0] output enable6  :       lut_data   =  {RW_CTRL,24'h3034_1a}; // MIPI 10-bit7  :       lut_data   =  {RW_CTRL,24'h3037_13}; // PLL root divider, bit[4], PLL pre-divider, bit[3:0]8  :       lut_data   =  {RW_CTRL,24'h3108_01}; // PCLK root divider, bit[5:4], SCLK2x root divider, bit[3:2]9  :        lut_data   =  {RW_CTRL,24'h3630_36};// SCLK root divider, bit[1:0]10 :        lut_data   =  {RW_CTRL,24'h3631_0e};11 :      lut_data   =  {RW_CTRL,24'h3632_e2};12 :      lut_data   =  {RW_CTRL,24'h3633_12};13 :      lut_data   =  {RW_CTRL,24'h3621_e0};14 :      lut_data   =  {RW_CTRL,24'h3704_a0};15 :      lut_data   =  {RW_CTRL,24'h3703_5a};16 :      lut_data   =  {RW_CTRL,24'h3715_78};17 :      lut_data   =  {RW_CTRL,24'h3717_01};18 :      lut_data   =  {RW_CTRL,24'h370b_60};19 :      lut_data   =  {RW_CTRL,24'h3705_1a};20 :      lut_data   =  {RW_CTRL,24'h3905_02};21 :      lut_data   =  {RW_CTRL,24'h3906_10};22 :      lut_data   =  {RW_CTRL,24'h3901_0a};23 :      lut_data   =  {RW_CTRL,24'h3731_12};24 :      lut_data   =  {RW_CTRL,24'h3600_08}; // VCM control25 :       lut_data   =  {RW_CTRL,24'h3601_33}; // VCM control26 :       lut_data   =  {RW_CTRL,24'h302d_60}; // system control27 :        lut_data   =  {RW_CTRL,24'h3620_52};28 :      lut_data   =  {RW_CTRL,24'h371b_20};29 :      lut_data   =  {RW_CTRL,24'h471c_50};30 :      lut_data   =  {RW_CTRL,24'h3a13_43}; // pre-gain = 1.047x31 :        lut_data   =  {RW_CTRL,24'h3a18_00}; // gain ceiling32 :      lut_data   =  {RW_CTRL,24'h3a19_f8}; // gain ceiling = 15.5x33 :     lut_data   =  {RW_CTRL,24'h3635_13};34 :      lut_data   =  {RW_CTRL,24'h3636_03};35 :      lut_data   =  {RW_CTRL,24'h3634_40};36 :      lut_data   =  {RW_CTRL,24'h3622_01};// 50/60Hz detection 50/60Hz 灯光条纹过滤37 :       lut_data   =  {RW_CTRL,24'h3c01_34}; // Band auto, bit[7]38 :     lut_data   =  {RW_CTRL,24'h3c04_28}; // threshold low sum39 :     lut_data   =  {RW_CTRL,24'h3c05_98}; // threshold high sum40 :        lut_data   =  {RW_CTRL,24'h3c06_00}; // light meter 1 threshold[15:8]41 :     lut_data   =  {RW_CTRL,24'h3c07_08}; // light meter 1 threshold[7:0]42 :      lut_data   =  {RW_CTRL,24'h3c08_00}; // light meter 2 threshold[15:8]43 :     lut_data   =  {RW_CTRL,24'h3c09_1c}; // light meter 2 threshold[7:0]44 :      lut_data   =  {RW_CTRL,24'h3c0a_9c}; // sample number[15:8]45 :       lut_data   =  {RW_CTRL,24'h3c0b_40}; // sample number[7:0]46 :        lut_data   =  {RW_CTRL,24'h3810_00}; // Timing Hoffset[11:8]47 :      lut_data   =  {RW_CTRL,24'h3811_10}; // Timing Hoffset[7:0]48 :       lut_data   =  {RW_CTRL,24'h3812_00}; // Timing Voffset[10:8]49 :      lut_data   =  {RW_CTRL,24'h3708_64};50 :      lut_data   =  {RW_CTRL,24'h4001_02}; // BLC start from line 251 :     lut_data   =  {RW_CTRL,24'h4005_1a}; // BLC always update52 :     lut_data   =  {RW_CTRL,24'h3000_00}; // enable blocks53 :     lut_data   =  {RW_CTRL,24'h3004_ff}; // enable clocks54 :     lut_data   =  {RW_CTRL,24'h300e_58}; // MIPI power down, DVP enable55 :       lut_data   =  {RW_CTRL,24'h302e_00};56 :      lut_data   =  {RW_CTRL,24'h4300_61}; // RGB,57 :      lut_data   =  {RW_CTRL,24'h501f_01}; // ISP RGB58 :       lut_data   =  {RW_CTRL,24'h440e_00};59 :      lut_data   =  {RW_CTRL,24'h5000_a7}; // Lenc on, raw gamma on, BPC on, WPC on, CIP on// AEC target 自动曝光控制60 :     lut_data   =  {RW_CTRL,24'h3a0f_30}; // stable range in high61 :      lut_data   =  {RW_CTRL,24'h3a10_28}; // stable range in low62 :       lut_data   =  {RW_CTRL,24'h3a1b_30}; // stable range out high63 :     lut_data   =  {RW_CTRL,24'h3a1e_26}; // stable range out low64 :      lut_data   =  {RW_CTRL,24'h3a11_60}; // fast zone high65 :        lut_data   =  {RW_CTRL,24'h3a1f_14}; // fast zone low// Lens correction for ? 镜头补偿66 :        lut_data   =  {RW_CTRL,24'h5800_23};67 :      lut_data   =  {RW_CTRL,24'h5801_14};68 :      lut_data   =  {RW_CTRL,24'h5802_0f};69 :      lut_data   =  {RW_CTRL,24'h5803_0f};70 :      lut_data   =  {RW_CTRL,24'h5804_12};71 :      lut_data   =  {RW_CTRL,24'h5805_26};72 :      lut_data   =  {RW_CTRL,24'h5806_0c};73 :      lut_data   =  {RW_CTRL,24'h5807_08};74 :      lut_data   =  {RW_CTRL,24'h5808_05};75 :      lut_data   =  {RW_CTRL,24'h5809_05};76 :      lut_data   =  {RW_CTRL,24'h580a_08};77 :      lut_data   =  {RW_CTRL,24'h580b_0d};78 :      lut_data   =  {RW_CTRL,24'h580c_08};79 :      lut_data   =  {RW_CTRL,24'h580d_03};80 :      lut_data   =  {RW_CTRL,24'h580e_00};81 :      lut_data   =  {RW_CTRL,24'h580f_00};82 :      lut_data   =  {RW_CTRL,24'h5810_03};83 :      lut_data   =  {RW_CTRL,24'h5811_09};84 :      lut_data   =  {RW_CTRL,24'h5812_07};85 :      lut_data   =  {RW_CTRL,24'h5813_03};86 :      lut_data   =  {RW_CTRL,24'h5814_00};87 :      lut_data   =  {RW_CTRL,24'h5815_01};88 :      lut_data   =  {RW_CTRL,24'h5816_03};89 :      lut_data   =  {RW_CTRL,24'h5817_08};90 :      lut_data   =  {RW_CTRL,24'h5818_0d};91 :      lut_data   =  {RW_CTRL,24'h5819_08};92 :      lut_data   =  {RW_CTRL,24'h581a_05};93 :      lut_data   =  {RW_CTRL,24'h581b_06};94 :      lut_data   =  {RW_CTRL,24'h581c_08};95 :      lut_data   =  {RW_CTRL,24'h581d_0e};96 :      lut_data   =  {RW_CTRL,24'h581e_29};97 :      lut_data   =  {RW_CTRL,24'h581f_17};98 :      lut_data   =  {RW_CTRL,24'h5820_11};99 :      lut_data   =  {RW_CTRL,24'h5821_11};100:      lut_data   =  {RW_CTRL,24'h5822_15};101:      lut_data   =  {RW_CTRL,24'h5823_28};102:      lut_data   =  {RW_CTRL,24'h5824_46};103:      lut_data   =  {RW_CTRL,24'h5825_26};104:      lut_data   =  {RW_CTRL,24'h5826_08};105:      lut_data   =  {RW_CTRL,24'h5827_26};106:      lut_data   =  {RW_CTRL,24'h5828_64};107:      lut_data   =  {RW_CTRL,24'h5829_26};108:      lut_data   =  {RW_CTRL,24'h582a_24};109:      lut_data   =  {RW_CTRL,24'h582b_22};110:      lut_data   =  {RW_CTRL,24'h582c_24};111:      lut_data   =  {RW_CTRL,24'h582d_24};112:      lut_data   =  {RW_CTRL,24'h582e_06};113:      lut_data   =  {RW_CTRL,24'h582f_22};114:      lut_data   =  {RW_CTRL,24'h5830_40};115:      lut_data   =  {RW_CTRL,24'h5831_42};116:      lut_data   =  {RW_CTRL,24'h5832_24};117:      lut_data   =  {RW_CTRL,24'h5833_26};118:      lut_data   =  {RW_CTRL,24'h5834_24};119:      lut_data   =  {RW_CTRL,24'h5835_22};120:      lut_data   =  {RW_CTRL,24'h5836_22};121:      lut_data   =  {RW_CTRL,24'h5837_26};122:      lut_data   =  {RW_CTRL,24'h5838_44};123:      lut_data   =  {RW_CTRL,24'h5839_24};124:      lut_data   =  {RW_CTRL,24'h583a_26};125:      lut_data   =  {RW_CTRL,24'h583b_28};126:      lut_data   =  {RW_CTRL,24'h583c_42};127:      lut_data   =  {RW_CTRL,24'h583d_ce}; // lenc BR offset// AWB 自动白平衡128:        lut_data   =  {RW_CTRL,24'h5180_ff}; // AWB B block129:       lut_data   =  {RW_CTRL,24'h5181_f2}; // AWB control130:       lut_data   =  {RW_CTRL,24'h5182_00}; // [7:4] max local counter, [3:0] max fast counter131:       lut_data   =  {RW_CTRL,24'h5183_14}; // AWB advanced132:      lut_data   =  {RW_CTRL,24'h5184_25};133:      lut_data   =  {RW_CTRL,24'h5185_24};134:      lut_data   =  {RW_CTRL,24'h5186_09};135:      lut_data   =  {RW_CTRL,24'h5187_09};136:      lut_data   =  {RW_CTRL,24'h5188_09};137:      lut_data   =  {RW_CTRL,24'h5189_75};138:      lut_data   =  {RW_CTRL,24'h518a_54};139:      lut_data   =  {RW_CTRL,24'h518b_e0};140:      lut_data   =  {RW_CTRL,24'h518c_b2};141:      lut_data   =  {RW_CTRL,24'h518d_42};142:      lut_data   =  {RW_CTRL,24'h518e_3d};143:      lut_data   =  {RW_CTRL,24'h518f_56};144:      lut_data   =  {RW_CTRL,24'h5190_46};145:      lut_data   =  {RW_CTRL,24'h5191_f8}; // AWB top limit146:     lut_data   =  {RW_CTRL,24'h5192_04}; // AWB bottom limit147:      lut_data   =  {RW_CTRL,24'h5193_70}; // red limit148:     lut_data   =  {RW_CTRL,24'h5194_f0}; // green limit149:       lut_data   =  {RW_CTRL,24'h5195_f0}; // blue limit150:        lut_data   =  {RW_CTRL,24'h5196_03}; // AWB control151:       lut_data   =  {RW_CTRL,24'h5197_01}; // local limit152:       lut_data   =  {RW_CTRL,24'h5198_04};153:      lut_data   =  {RW_CTRL,24'h5199_12};154:      lut_data   =  {RW_CTRL,24'h519a_04};155:      lut_data   =  {RW_CTRL,24'h519b_00};156:      lut_data   =  {RW_CTRL,24'h519c_06};157:      lut_data   =  {RW_CTRL,24'h519d_82};158:      lut_data   =  {RW_CTRL,24'h519e_38}; // AWB control// Gamma 伽玛曲线159:      lut_data   =  {RW_CTRL,24'h5480_01}; // Gamma bias plus on, bit[0]160:        lut_data   =  {RW_CTRL,24'h5481_08};161:      lut_data   =  {RW_CTRL,24'h5482_14};162:      lut_data   =  {RW_CTRL,24'h5483_28};163:      lut_data   =  {RW_CTRL,24'h5484_51};164:      lut_data   =  {RW_CTRL,24'h5485_65};165:      lut_data   =  {RW_CTRL,24'h5486_71};166:      lut_data   =  {RW_CTRL,24'h5487_7d};167:      lut_data   =  {RW_CTRL,24'h5488_87};168:      lut_data   =  {RW_CTRL,24'h5489_91};169:      lut_data   =  {RW_CTRL,24'h548a_9a};170:      lut_data   =  {RW_CTRL,24'h548b_aa};171:      lut_data   =  {RW_CTRL,24'h548c_b8};172:      lut_data   =  {RW_CTRL,24'h548d_cd};173:      lut_data   =  {RW_CTRL,24'h548e_dd};174:      lut_data   =  {RW_CTRL,24'h548f_ea};175:      lut_data   =  {RW_CTRL,24'h5490_1d};// color matrix 色彩矩阵176:      lut_data   =  {RW_CTRL,24'h5381_1e}; // CMX1 for Y177:        lut_data   =  {RW_CTRL,24'h5382_5b}; // CMX2 for Y178:        lut_data   =  {RW_CTRL,24'h5383_08}; // CMX3 for Y179:        lut_data   =  {RW_CTRL,24'h5384_0a}; // CMX4 for U180:        lut_data   =  {RW_CTRL,24'h5385_7e}; // CMX5 for U181:        lut_data   =  {RW_CTRL,24'h5386_88}; // CMX6 for U182:        lut_data   =  {RW_CTRL,24'h5387_7c}; // CMX7 for V183:        lut_data   =  {RW_CTRL,24'h5388_6c}; // CMX8 for V184:        lut_data   =  {RW_CTRL,24'h5389_10}; // CMX9 for V185:        lut_data   =  {RW_CTRL,24'h538a_01}; // sign[9]186:       lut_data   =  {RW_CTRL,24'h538b_98}; // sign[8:1]// UV adjust UV 色彩饱和度调整187:      lut_data   =  {RW_CTRL,24'h5580_06}; // saturation on, bit[1]188:     lut_data   =  {RW_CTRL,24'h5583_40};189:      lut_data   =  {RW_CTRL,24'h5584_10};190:      lut_data   =  {RW_CTRL,24'h5589_10};191:      lut_data   =  {RW_CTRL,24'h558a_00};192:      lut_data   =  {RW_CTRL,24'h558b_f8};193:      lut_data   =  {RW_CTRL,24'h501d_40}; // enable manual offset of contrast// CIP 锐化和降噪194:      lut_data   =  {RW_CTRL,24'h5300_08}; // CIP sharpen MT threshold 1195:        lut_data   =  {RW_CTRL,24'h5301_30}; // CIP sharpen MT threshold 2196:        lut_data   =  {RW_CTRL,24'h5302_10}; // CIP sharpen MT offset 1197:       lut_data   =  {RW_CTRL,24'h5303_00}; // CIP sharpen MT offset 2198:       lut_data   =  {RW_CTRL,24'h5304_08}; // CIP DNS threshold 1199:       lut_data   =  {RW_CTRL,24'h5305_30}; // CIP DNS threshold 2200:       lut_data   =  {RW_CTRL,24'h5306_08}; // CIP DNS offset 1201:      lut_data   =  {RW_CTRL,24'h5307_16}; // CIP DNS offset 2202:      lut_data   =  {RW_CTRL,24'h5309_08}; // CIP sharpen TH threshold 1203:        lut_data   =  {RW_CTRL,24'h530a_30}; // CIP sharpen TH threshold 2204:        lut_data   =  {RW_CTRL,24'h530b_04}; // CIP sharpen TH offset 1205:       lut_data   =  {RW_CTRL,24'h530c_06}; // CIP sharpen TH offset 2206:       lut_data   =  {RW_CTRL,24'h5025_00};207:      lut_data   =  {RW_CTRL,24'h3008_02}; // wake up from standby, bit[6]// input clock 24Mhz, PCLK 84Mhz208:      lut_data   =  {RW_CTRL,24'h3035_21}; // PLL209:       lut_data   =  {RW_CTRL,24'h3036_69}; // PLL210:       lut_data   =  {RW_CTRL,24'h3c07_07}; // lightmeter 1 threshold[7:0]211:       lut_data   =  {RW_CTRL,24'h3820_47}; // flip212:      lut_data   =  {RW_CTRL,24'h3821_01}; // no mirror213:     lut_data   =  {RW_CTRL,24'h3814_31}; // timing X inc214:      lut_data   =  {RW_CTRL,24'h3815_31}; // timing Y inc215:      lut_data   =  {RW_CTRL,24'h3800_00}; // HS216:        lut_data   =  {RW_CTRL,24'h3801_00}; // HS217:        lut_data   =  {RW_CTRL,24'h3802_00}; // VS218:        lut_data   =  {RW_CTRL,24'h3803_fa}; // VS219:        lut_data   =  {RW_CTRL,24'h3804_0a}; // HW  :     lut_data   =  HE}220:      lut_data   =  {RW_CTRL,24'h3805_3f}; // HW  :     lut_data   =  HE}221:      lut_data   =  {RW_CTRL,24'h3806_06}; // VH  :     lut_data   =  VE}222:      lut_data   =  {RW_CTRL,24'h3807_a9}; // VH  :     lut_data   =  VE}223:      lut_data   =  {RW_CTRL,24'h3808_05}; // DVPHO 1280224:        lut_data   =  {RW_CTRL,24'h3809_00}; // DVPHO225:     lut_data   =  {RW_CTRL,24'h380a_02}; // DVPVO 720226:     lut_data   =  {RW_CTRL,24'h380b_d0}; // DVPVO227:     lut_data   =  {RW_CTRL,24'h380c_07}; // HTS228:       lut_data   =  {RW_CTRL,24'h380d_64}; // HTS229:       lut_data   =  {RW_CTRL,24'h380e_02}; // VTS230:       lut_data   =  {RW_CTRL,24'h380f_e4}; // VTS231:       lut_data   =  {RW_CTRL,24'h3813_04}; // timing V offset232:       lut_data   =  {RW_CTRL,24'h3618_00};233:      lut_data   =  {RW_CTRL,24'h3612_29};234:      lut_data   =  {RW_CTRL,24'h3709_52};235:      lut_data   =  {RW_CTRL,24'h370c_03};236:      lut_data   =  {RW_CTRL,24'h3a02_02}; // 60Hz max exposure237:     lut_data   =  {RW_CTRL,24'h3a03_e0}; // 60Hz max exposure238:     lut_data   =  {RW_CTRL,24'h3a14_02}; // 50Hz max exposure239:     lut_data   =  {RW_CTRL,24'h3a15_e0}; // 50Hz max exposure240:     lut_data   =  {RW_CTRL,24'h4004_02}; // BLC line number241:       lut_data   =  {RW_CTRL,24'h3002_1c}; // reset JFIFO, SFIFO, JPG242:       lut_data   =  {RW_CTRL,24'h3006_c3}; // disable clock of JPEG2x, JPEG243:     lut_data   =  {RW_CTRL,24'h4713_03}; // JPEG mode 3244:       lut_data   =  {RW_CTRL,24'h4407_04}; // Quantization scale245:        lut_data   =  {RW_CTRL,24'h460b_37};246:      lut_data   =  {RW_CTRL,24'h460c_20};247:      lut_data   =  {RW_CTRL,24'h4837_16}; // MIPI global timing248:        lut_data   =  {RW_CTRL,24'h3824_04}; // PCLK manual divider249:       lut_data   =  {RW_CTRL,24'h5001_83}; // SDE on, CMX on, AWB on250:        lut_data   =  {RW_CTRL,24'h3503_00}; // AEC/AGC on                  251:      lut_data   =  {RW_CTRL,24'h4740_20}; // VS 1//252:        lut_data   =  {RW_CTRL,24'h503d_80}; // color bar 选择彩条输出//253:        lut_data   =  {RW_CTRL,24'h4741_00}; //default   :    lut_data   =  0;endcaseendendmodule 

IIC端口模块

//IIC端口模块
`include "param.v"
module  i2c_itfc(input             clk         ,input             rst_n       ,input       [4:0] cmd         ,input       [7:0] wr_din      ,input             sda_in      ,output  reg       sda_en      ,output  reg       sda_out     ,output  reg       scl         ,output  reg  [7:0]rd_out      , output  reg       rd_out_vld  ,output  reg       done0       ,output  reg       ack
);
//高位先发msb
parameter   PAN=150,DOW_TIME=75,WR_TIME =15, //发送数据不管RD_TIME =90;//采集数据
localparam    IDLE      = 7'b000_0001,START     = 7'b000_0010,WRITE     = 7'b000_0100,ACTACK    = 7'b000_1000,READ      = 7'b001_0000,SENDACK   = 7'b010_0000,STOP      = 7'b100_0000;
reg [6:0]           state;
reg [6:0]           state_next;
wire                idle_start   ;
wire                start_write  ;
wire                write_actack ;
wire                actack_start ;
wire                actack_write ;
wire                actack_read  ;
wire                read_sendack ;
wire                sendack_read ;
wire                sendack_stop ;
wire                stop_idle    ;
wire                actack_stop  ;reg  [15:0] max;
reg  [15:0] cnt_bit;
wire        add_cnt_bit;
wire        end_cnt_bit;
reg  [3:0]  cnt_byte;
wire        add_cnt_byte;
wire        end_cnt_byte;
reg  [7:0]  data_flag   ;  //接收数据暂存always@(posedge  clk  or  negedge  rst_n)  beginif(!rst_n) beginstate<=IDLE;endelse beginstate<=state_next;end
end
always@(*)  begincase(state)IDLE : beginif(idle_start)  beginstate_next=START;endelse  beginstate_next<=state;endendSTART: beginif(start_write)  beginstate_next=WRITE;endelse beginstate_next<=state;endendWRITE: beginif(write_actack)  beginstate_next=ACTACK;endelse beginstate_next<=state;endendACTACK:  beginif(actack_start)  beginstate_next=START;endelse if(actack_write)  beginstate_next=WRITE;endelse if(actack_read)   beginstate_next=READ;endelse if(actack_stop)   beginstate_next=STOP;endelse beginstate_next<=state;endendREAD : beginif(read_sendack)  beginstate_next=SENDACK;endelse  beginstate_next<=state;endendSENDACK: beginif(sendack_stop)  beginstate_next=STOP; endelse if(sendack_read)  beginstate_next=READ;endelse  beginstate_next<=state;endendSTOP : beginif(stop_idle)  beginstate_next=IDLE;endelse  beginstate_next<=state;endenddefault:state_next<=IDLE;endcase
end
assign idle_start  =state==IDLE   && (cmd==`CMD_EN                          )  ;  //开始工作
assign start_write =state==START  && (end_cnt_byte                          )  ;
assign write_actack=state==WRITE  && (end_cnt_byte                          )  ;
assign actack_start=state==ACTACK && (cmd==`CMD_RDST &&end_cnt_byte         )  ;   //读数据的时候发起始位1次
assign actack_write=state==ACTACK && (cmd==`CMD_WR   &&end_cnt_byte         )  ;  //写数据
assign actack_read =state==ACTACK && (cmd==`CMD_RD   &&end_cnt_byte         )  ;   //接收数据
assign actack_stop =state==ACTACK && ((cmd==`CMD_NO  &&end_cnt_byte)||ack==1)  ;   //写完数据接发停止位 或者ack无应答
assign read_sendack=state==READ   && ( end_cnt_byte                         )  ;
assign sendack_read=state==SENDACK&& ( end_cnt_byte                         )  ;
assign sendack_stop=state==SENDACK&& (cmd==`CMD_NO &&end_cnt_byte           )  ; //发停止位
assign stop_idle   =state==STOP   && (end_cnt_byte                          )  ;
//一个字节周期
always@(posedge  clk   or negedge  rst_n)  beginif(!rst_n)  begincnt_bit<=0;endelse  if(end_cnt_bit) begincnt_bit<=0;endelse  if(add_cnt_bit) begincnt_bit<=cnt_bit+1'b1;end
end
assign add_cnt_bit=state!=IDLE;
assign end_cnt_bit=add_cnt_bit && cnt_bit==PAN-1;
//cnt_byte多少个字节周期
always@(posedge  clk  or  negedge  rst_n)  beginif(!rst_n)  begincnt_byte<=0;endelse  if(end_cnt_byte) begincnt_byte<=0;endelse  if(add_cnt_byte) begincnt_byte<=cnt_byte+1'b1;end
end
assign add_cnt_byte=state!=IDLE && end_cnt_bit;
assign end_cnt_byte=add_cnt_byte && cnt_byte==max-1;  //cnt_byte==MAX-1之后等下个周期add_cnt_byte到了才为零
///max
always@(  *   )  beginif(!rst_n)  beginmax=0;endelse   begincase(state)START  :  max=1;WRITE  :  max=8;ACTACK :  max=1;READ   :  max=8;SENDACK:  max=1;STOP   :  max=1;default:max=0;endcase    end
end
//scl
always@(posedge  clk  or  negedge  rst_n)  beginif(!rst_n)  beginscl<=1;endelse if( cnt_bit==DOW_TIME-1 ) begin  //scl<=1;endelse  if( start_write|| ( (state==WRITE||state==READ||state==ACTACK||state==SENDACK)&&cnt_bit==PAN-1&&actack_stop==0 ) ) beginscl<=0;   //数据传输状态scl先低电平再高电平 end else  if(state==START ||state==STOP) begin  //起始状态,stop状态高电平scl<=1;end
end
//ack
always@(posedge  clk  or  negedge  rst_n)  beginif(!rst_n)  beginack<=0;endelse if(state==ACTACK && cnt_bit==RD_TIME) begin   ack<=sda_in;      //发数据时,反馈ack是否应答endelse  if(  stop_idle ) begin     //一次数据发送结束,反馈一个信号ack<=1;endelse  beginack<=0;end
end
//sda_en
always@(posedge  clk or negedge  rst_n)  beginif(!rst_n)  beginsda_en<=1;endelse if(actack_read||write_actack||sendack_read) begin   //接收应答信号 和 读数据时候  为低电平sda_en<=0;endelse  if( read_sendack ||actack_start||actack_write||actack_stop) beginsda_en<=1;end
end
//sda_out
always@(posedge  clk  or  negedge  rst_n)  beginif(!rst_n)  beginsda_out<=1;   //空闲为1endelse if(state==START&& cnt_bit==DOW_TIME )  begin    //起始状态,sda由高拉低sda_out<=0;endelse if(state==WRITE && cnt_bit==WR_TIME ) begin   //写数据状态,scl低电平写数据sda_out<=wr_din[7-cnt_byte];  //高字节先发endelse  if(read_sendack&&cmd==`CMD_NO) begin   //发送应答信号状态, NO_ACKsda_out<=1;endelse  if(   read_sendack    ) begin   //发送应答信号状态,ACKsda_out<=0;endelse if( actack_stop|| sendack_stop  )  begin    //停止状态先拉低sda_out<=0;endelse if( state==STOP && cnt_bit==DOW_TIME )  begin    //停止状态又由低拉高sda_out<=1;end
end
//sda_in  data_flag
always@(posedge  clk  or  negedge  rst_n)  beginif(!rst_n)  begindata_flag<=0;endelse if(state==READ && cnt_bit==RD_TIME-1 ) begin   data_flag[8-cnt_byte]<=sda_in;end
end
//done
always@(posedge  clk or  negedge  rst_n)  beginif(!rst_n)  begindone0<=0;endelse if( ((state==ACTACK|| state==READ )&&cnt_bit==PAN-4 && cnt_byte==max-1)||stop_idle) begin   //done信号提前3个周期给出去,或者状态结束(反馈到控制模块)done0<=1;endelse   begindone0<=0;end
end
//rd_out  rd_out_vld
always@(posedge  clk  or  negedge  rst_n)  beginif(!rst_n)  beginrd_out<=0;rd_out_vld<=0;endelse if( state==READ &&cnt_bit==PAN-1 ) begin   rd_out<=data_flag;rd_out_vld<=1;endelse  beginrd_out_vld<=0;end
end
endmodule

IIC控制模块

//IIC控制模块
`include "param.v"
module   sio_drive(input               clk          ,input               rst_n        ,output reg          redy         ,   //写数据进来要求。1代表空闲中,0代表工作中input               data_en      ,   //lut数据传输开始使能input      [24:0]   data_l       ,   //lut数据模块output     [7:0]    dout         , //读出的数据output              dout_vld     , //读出有效数据output    reg       no_ack       , //无应答
//端口模块output reg [4:0]    cmd          ,output reg [7:0]    data_i2c     ,   //传给端口模块数据input      [7:0]    i2c_din      , //端口模块传回数据input               i2c_din_vld  ,     input               done         ,  //上次数据传输完成标志  input               ack              //端口模块
);
//
parameter       WR_NUM=3'd4,   //读操作一共周期数RD_NUM=3'd5,   //写操作一共周期数WR_ID =8'h78,  //摄像头写IDRD_ID =8'h79;  //摄像头读IDreg [2:0]       cnt_byte        ;
wire            add_cnt_byte    ;
wire            end_cnt_byte    ;
reg  [2:0]      MAX             ;
wire            rw_ctrl         ;
reg  [23:0]     data_lut        ; //数据暂存
reg             wr_rd           ;
reg  [1:0]      per             ;  assign  rw_ctrl = data_en ? data_l[24]:1'b0;       //是写+读  或者只写
always @(posedge clk or negedge rst_n)begin if(!rst_n)begindata_lut<=0;end else if(data_en)begin data_lut<=data_l[23:0] ;end
end
//wr_rd   per
always@(posedge clk or negedge rst_n)  beginif(!rst_n)  beginper<=0;wr_rd<=0;   //0代表读,1代表写endelse if( rw_ctrl==1  && data_en ) begin   //写模式+读模式per<=2;   wr_rd<=1;endelse if(rw_ctrl==0 && data_en)  begin  //只写模式per<=1;   wr_rd<=1;endelse if(cnt_byte==MAX && ack==1)  begin   //ack只有一个周期per<=per-1'b1;wr_rd<=0;    //读数据end
end
//redy
always@(* )  beginif(  per==0  )  begin  //per==1 代表空闲状态redy=1'b1 ;endelse     beginredy=0 ;end
end
//no_ack
always@(posedge  clk  or negedge  rst_n)  beginif(!rst_n)  beginno_ack<=0;endelse  if(cnt_byte>0&&cnt_byte<MAX)  beginno_ack<=ack;    endelse     beginno_ack<=0; end
end
//cnt_byte
always@(posedge  clk  or negedge  rst_n)  beginif(!rst_n)  begincnt_byte<=0;endelse  if(end_cnt_byte && ack==1)  begincnt_byte<=0;endelse  if(end_cnt_byte  )  begincnt_byte<=cnt_byte;endelse if(add_cnt_byte)   begincnt_byte<=cnt_byte+1'b1;end
end
assign  add_cnt_byte= done==1  ;    //提前一个周期给反馈信号
assign  end_cnt_byte=(add_cnt_byte && cnt_byte==MAX)||no_ack ;  //最后一个数据发完再接收一个done
//MAX
always@(posedge  clk  or negedge  rst_n)  beginif(!rst_n)  beginMAX<=0;endelse  if(wr_rd==1 && cnt_byte==0)  beginMAX<=WR_NUM ;endelse  if(wr_rd==0 && cnt_byte==0 )   beginMAX<=RD_NUM ;end
end
//输出给端口模块数据data_i2c
always@(posedge  clk  or negedge  rst_n)  beginif(!rst_n)  begindata_i2c<=0;cmd<=0;endelse  if( wr_rd==1  )  begin  //writeif( (per==1 ||per==2)&&cnt_byte==0 ) begin   //写模式cmd<=`CMD_EN;  //端口模块开始工作data_i2c<=WR_ID;endelse case(cnt_byte)1   :begin  data_i2c<=data_lut[23:16];cmd<=`CMD_WR;end                        //地址2   :begin  data_i2c<=data_lut[15:8] ;cmd<=`CMD_WR;end                             //数据3   :begin  data_i2c<=data_lut[7:0]  ;cmd<=`CMD_WR;end  4   :begincmd<=`CMD_NO;   end                                           default:data_i2c<=0;endcaseendelse  if( wr_rd==0  )  begin   //readif( (per==1 ||per==2)&&cnt_byte==0 ) begincmd<=`CMD_EN;    //端口模块开始工作data_i2c<=WR_ID;endelse case(cnt_byte)1   :begin data_i2c<=data_lut[23:16];cmd<=`CMD_WR;end2   :begin data_i2c<=data_lut[15:8];cmd<=`CMD_WR;end3   :begin data_i2c<=RD_ID;cmd<=`CMD_RDST;end4   :begin cmd<=`CMD_RD;end5   :begincmd<=`CMD_NO;enddefault:begin data_i2c<=0;cmd<=0;endendcaseend
endassign dout    =i2c_din    ;assign dout_vld=i2c_din_vld;
endmodule

图像采集模块 

//图像采集模块
`include "param.v"
module  ov5640_capture(input                   clk             ,input                   rst_n           ,input                   href            ,//行同步input                   vsync           ,//帧同步input                   config_done     , //配置模块完成input            [7:0]  din             ,
//输出      output   reg     [15:0] dout            ,  //信号与数据和数据有效 在时钟周期内是同步的,output   reg            dout_vld        ,  //信号与数据和数据有效 在时钟周期内是同步的,output   reg            sop             ,  //信号与数据和数据有效 在时钟周期内是同步的,包头output   reg            eop             ,   //信号与数据和数据有效 在时钟周期内是同步的,包尾output   reg  [23:0] cnt_dout_vld  );
reg  [11:0]  cnt_col;   //行计数器 2560
wire        add_cnt_col;
wire        end_cnt_col;reg  [9:0]  cnt_row;   //场计数器 720
wire        add_cnt_row;
wire        end_cnt_row;reg         vsync_r; //一帧的起点
reg         href_flag;
reg         dout_lvd_en;//帧起点同步
always@(posedge clk or negedge rst_n) beginif(!rst_n)  beginvsync_r<=0;endelse if( vsync && config_done) begin   //摄像头配置完成vsync_r<=1'b1   ;endelse if(dout_vld) begin  vsync_r<=0;end
end
always @(posedge clk or negedge rst_n)begin if(!rst_n)beginhref_flag <= 0;end else  if(dout_lvd_en)  beginhref_flag<=0; endelse if( href )begin href_flag<=1'b1;end else begin href_flag<=0; end
end
//行计数
always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt_col <= 0;end else if(add_cnt_col)begin if(end_cnt_col)begin cnt_col <= 0;endelse begin cnt_col <= cnt_col + 1'b1;end end
end
assign add_cnt_col = href_flag ;
assign end_cnt_col = add_cnt_col && cnt_col ==`COL_MAX-1  ;//1280
//场计数
always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt_row <= 0;end else if(add_cnt_row)begin if(end_cnt_row)begin cnt_row <= 0;endelse begin cnt_row <= cnt_row + 1'b1;end end
end
assign add_cnt_row = end_cnt_col;
assign end_cnt_row = add_cnt_row && cnt_row ==`ROW_MAX-1;  //720always @(posedge clk or negedge rst_n)begin if(!rst_n)  begindout<=0;endelse   begin dout[15-cnt_col[0]*8 -:8] <= din;end
end
//dout_vld   数据晚一个周期
always @(posedge clk or negedge rst_n)begin if(!rst_n)  begindout_vld<=0;endelse if(add_cnt_col   && cnt_col[0]==1)begin dout_vld<=1'b1;end else begin dout_vld<=0;end
end
//sop
always @(posedge clk or negedge rst_n)begin if(!rst_n)beginsop <= 0;end else if( add_cnt_col && cnt_col[0]==1&& vsync_r  )begin  sop<=1'b1;end else  begin sop<=0;    end
end
always @(*)begin if(end_cnt_row)begin eop=1'b1; end else begin eop=1'b0; end
end//可修改
always @(posedge clk or negedge rst_n)begin if(!rst_n)begindout_lvd_en <= 0;end else if(eop)begin dout_lvd_en<=1'b1;endelse if( vsync    )begin   dout_lvd_en<=1'b0;end
end//仿真测试用
always@(posedge  clk or  negedge  rst_n)  beginif(!rst_n)   begincnt_dout_vld<=0;endelse if(eop)  begincnt_dout_vld<=0;endelse  if( add_cnt_col &&   dout_vld==1'b1)  begincnt_dout_vld<=cnt_dout_vld+1'b1;endendendmodule 

异步FIFO控制模块

        此模块采用FIFO18位宽:数据+sop+eop判断

//异步FIFO处理跨时域问题,判断是否丢帧问题
`include "param.v"
//wrfifo 18位
//rdfifo 16位
module  fifo_ctrl (input               clk             , //100minput               rst_n           ,input               clk_in          ,  //84minput               clk_out         ,  //75m//采集模块数据input    [15:0]     din_pixel        ,input               din_pixel_vld    ,input               sop              ,input               eop              , //vga模块input               req_vga          ,output  reg[15:0]   data_vga         ,output  reg         data_vga_vld     ,//wrfifo 读出给sdram数据output    [11:0]    wrfifo_rdusedw   ,output    [17:0]    wrfifo_q         , input               wrfifo_rdreq     ,//rdfifo  sdram写进数据input     [15:0]    rdfifo_data      ,input               rdfifo_wrreq     ,  output  reg         sop_vld          , //一帧数据丢失,不能读wrfifo数据output    [10:0]    rdfifo_wrusedw   ,output  reg[23:0]     cnt_num        ,output  reg[23:0]     cnt_vld
);//wrfifo
reg   [17:0]            wrfifo_data         ;
//reg                     eop_vld           ;
reg                     fail                ;
reg                     wrfifo_wrreq        ;
wire                    wrfifo_wrfull       ;
//rdfifo
wire                    rdfifo_rdempty      ;
wire   [15:0]           rdfifo_q            ;
wire                    rdfifo_rdreq        ;
reg                     rdreq_flag          ;
wire    [11:0]          wrfifo_wusedw       ;
reg                     sop_flag            ;
wire    [17:0]          wrfifo_qout         ;//wrFIFO输出wrfifo     u_wrfifo(.aclr           (~rst_n             )   ,.data           (wrfifo_data        )   ,.rdclk          (clk                )   ,.rdreq          (rdreq_flag         )   ,.wrclk          (clk_in             )   ,.wrreq          (wrfifo_wrreq       )   ,.q              (wrfifo_qout        )   ,.rdusedw        (wrfifo_rdusedw     )   ,.wrfull         (wrfifo_wrfull      )   ,.wrusedw        (wrfifo_wusedw      ));//*****************************************WRFIFO*******************************************//always @(posedge clk_in or negedge rst_n)begin if(!rst_n)beginwrfifo_data <= 0;end else begin wrfifo_data<={sop,eop,din_pixel} ;end end//sop_vld为1代表这一帧数据丢失always @(posedge clk  or negedge rst_n)begin   //写时钟下if(!rst_n)begin sop_vld<=1'b0;end else   if(  wrfifo_rdusedw>4050  )begin sop_vld <= 1'b1;end else  if(  wrfifo_qout[17] /* sop */)  begin   //写数据时钟sop_vld<=1'b0;endendalways @( * )begin if(sop_vld )begin rdreq_flag=1'b1;end else   beginrdreq_flag = wrfifo_rdreq;endendalways @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt_num <= 0;end else if(wrfifo_qout[16])  begincnt_num<=0;endelse if(sop_vld==0 &&rdreq_flag )begin cnt_num<=cnt_num+1'b1;endendassign  wrfifo_q=(sop_vld==0)?wrfifo_qout:0;always @(posedge clk_in or negedge rst_n)begin if(!rst_n)beginsop_flag <= 0;end else if(sop==1'b1)begin sop_flag<=1'b1;end else   if(eop)begin sop_flag <= 0;end endalways @(posedge clk_in or negedge rst_n)begin if(!rst_n)beginwrfifo_wrreq <= 0;end else if(wrfifo_wrfull==1'b0)begin wrfifo_wrreq<=(sop_flag&& din_pixel_vld )||sop ;end end//tb测试用always @(posedge clk_in or negedge rst_n)begin if(!rst_n)begincnt_vld <= 0;end else  if(sop_flag==0)  begincnt_vld<=0;endelse   if(wrfifo_wrreq)begin cnt_vld<=cnt_vld+1'b1 ;end end//************************rdfifo****************************************//rdfifo    u_rdfifo(.aclr          (~rst_n             )  ,.data           (rdfifo_data        )  ,.rdclk          (clk_out            )  ,.rdreq          (rdfifo_rdreq       )  ,.wrclk          (clk               )  ,        .wrreq          (rdfifo_wrreq       )  ,.q              (rdfifo_q           )  ,.rdempty        (rdfifo_rdempty     )  ,.wrusedw        (rdfifo_wrusedw     )  );//data_vga   //data_vga_vld always@(posedge clk_out or negedge rst_n)   beginif(!rst_n) begindata_vga<=0;data_vga_vld<=0;endelse begindata_vga<=rdfifo_q;data_vga_vld<=rdfifo_rdreq;endendassign  rdfifo_rdreq= rdfifo_rdempty==1'b0 ? req_vga : 1'b0 ;endmodule 

SDRAM控制模块

SDRAM控制模块`include    "param.v"
module sdram_ctrl (
input                   clk                ,
input                   rst_n              ,
//wrfifo
input           [1:0]   wrfifo_seop           ,
input           [11:0]  wrfifo_rdusedw     ,
input                   sop_vld            ,
//rdfifo
input           [10:0]   rdfifo_wrusedw    ,
output  reg     [15:0]  dout_fifo          ,
output  reg             dout_fifo_vld      ,
//接收端口模块数据
input           [2:0]   done               ,
input           [15:0]  din_ctrl           ,
input                   din_ctrl_vld       ,
//传给端口模块
output  reg     [23:0]  addr_iftc          ,
output  reg             wr_en_out          ,
output  reg             rd_en_out          ,
output  reg             sop                 ,
output  reg             eop
);//状态参数
localparam  IDLE  =5'b0000_1,ITFCEN=5'b0001_0,ADDR  =5'b0010_0,WRITE =5'b0100_0,READ  =5'b1000_0;
reg [4:0]   state;
reg [4:0]   state_next;
wire        idle_itfcen;
wire        itfcen_addr;
wire        idle_addr ;
wire        addr_write;
wire        addr_read ;
wire        write_idle;
wire        read_idle ;//信号参数
wire [15:0]      din     ;
reg             wr_en   ;
reg             rd_en   ;reg  [21:0]   addr_wr;
wire          add_addr_wr;
wire          end_addr_wr;reg  [21:0]   addr_rd;
wire          add_addr_rd;
wire          end_addr_rd;reg          flag       ;  reg [1:0]    wr_bank    ;
reg [1:0]    rd_bank    ;
reg          seop       ;
reg          bank_turn  ;//bank翻转记录
//打拍reg         sop_flag;wire           nedge;wire          pedge;reg           sop_vld_r0;reg          sop_vld_r1;//********************************sop+打拍***************************************8/always @(posedge clk or negedge rst_n)begin if(!rst_n)beginsop<=0;eop<=0;endelse if(state==WRITE||write_idle)  begineop<=wrfifo_seop[0];sop<=0;endelse  if(addr_write ) beginsop<=wrfifo_seop[1];eop<=0;endelse beginsop<=0;eop<=0; end
end//**************************状态机**********************************************/
always @(posedge clk or negedge rst_n)begin if(!rst_n)beginstate <= IDLE;end else begin state <= state_next;end
end
always @(*)begin case(state)IDLE :beginif(idle_itfcen)  beginstate_next=ITFCEN;endelse beginstate_next=state;endendITFCEN :beginif(itfcen_addr)  beginstate_next=ADDR;endelse beginstate_next=state;endendADDR: beginif(addr_write)  beginstate_next=WRITE;endelse if(addr_read)  beginstate_next=READ;endelse beginstate_next=state;endendWRITE:beginif(write_idle)  beginstate_next=IDLE;endelse beginstate_next=state;endendREAD :beginif(read_idle)  beginstate_next=IDLE;endelse beginstate_next=state;endenddefault:state_next=IDLE;endcase
end
assign    idle_itfcen =state==IDLE  && (wr_en ||rd_en       );  //en必须只有一个周期
assign    itfcen_addr =state==ITFCEN &&(rd_en_out||wr_en_out) ;//仲裁后,判断读写
assign    addr_write=state==ADDR  && (flag==1'b1            ); //提示下一周期给数据
assign    addr_read =state==ADDR  && (flag==1'b0            );//读,给一次地址就行
assign    write_idle=state==WRITE && (done[2]==1'b0         );//提示下一周期停止给数据
assign    read_idle =state==READ  && (done[2]==1'b0         );//done[2]代表一次突发完成//****************************地址*****************************************/always @(posedge clk or negedge rst_n)begin if(!rst_n)beginaddr_wr <=1'b0;end else if(add_addr_wr)begin if(end_addr_wr)begin addr_wr <=1'b0;endelse begin addr_wr <= addr_wr + `BUSRT_MAX;end end
end
assign add_addr_wr = write_idle; //突发完后再加一次
assign end_addr_wr = add_addr_wr && addr_wr ==`FPS-`BUSRT_MAX  ; //一帧像素-突发长度1800-1
always @(posedge clk or negedge rst_n)begin if(!rst_n)beginaddr_rd <=1'b0;end else if(add_addr_rd)begin if(end_addr_rd)begin addr_rd <=1'b0;endelse begin addr_rd <= addr_rd + `BUSRT_MAX;end end
end
assign add_addr_rd = read_idle;
assign end_addr_rd = add_addr_rd && addr_rd == `FPS-`BUSRT_MAX  ;//*******************************************seop***************************************/////
always @(posedge clk or negedge rst_n)begin if(!rst_n)beginseop <= 1'b1;end else   if( end_addr_wr )begin seop <=1'b0;                                end else if(bank_turn==0   )  begin  //seop突发写标志,1才能写。0 不能写seop <= 1'b1;end
end
// rd_bank, wr_bank, bank_turn状态  写模式翻转记录
always @(posedge clk or negedge rst_n)begin if(!rst_n)beginwr_bank <= 2'b00;rd_bank <=2'b11;bank_turn<=1'b0;  //状态翻转记录    0代表已经翻转,可以写。1代表还未翻转等待翻转中end else if(  seop==0 && end_addr_rd      )begin wr_bank <=~wr_bank;rd_bank <=~rd_bank;bank_turn<=1'b0;   end else if(   seop==1'b1 && wr_en  )  beginbank_turn<=1'b1;        //翻转后end
end
//bank_flag  第一个bank写完标志//*****************************突发信号******************************/
always @(posedge clk or negedge rst_n)begin   if(!rst_n)beginsop_vld_r0 <=1'b0;sop_vld_r1 <=1'b0;end else    begin   //sop_vld_r0 <=sop_vld;sop_vld_r1 <=sop_vld_r0;end
endassign  pedge=sop_vld_r0&& ~sop_vld_r1;assign  nedge=~sop_vld_r0&& sop_vld_r1;always @(posedge clk or negedge rst_n)begin if(!rst_n)beginsop_flag <=1'b0;end else if(pedge)  beginsop_flag<=1'b1;endelse if(nedge)  beginsop_flag<=1'b0;endend
always @(posedge clk or negedge rst_n)begin if(!rst_n)beginwr_en <=1'b0;end else if(idle_itfcen)  beginwr_en<=1'b0;endelse if( (wrfifo_rdusedw >=`BUSRT_MAX-1) && seop==1'b1 && state==IDLE && sop_flag==0  )begin wr_en<=1'b1;  //代表一次突发写 end
end
//rd_en//代表一次突发读
always @(posedge clk or negedge rst_n)begin  if(!rst_n)beginrd_en <=1'b0;end else if(idle_itfcen)  begin   rd_en <=1'b0;endelse if(/*rd_flag && */rdfifo_wrusedw<`FIFO_L && state==IDLE )begin  //读数据,rdfifo数据量小于300,且端口模块空闲中rd_en<=1'b1;end else  if(rdfifo_wrusedw>`FIFO_H) begin    //读数据,rdfifo数据量大于1600,rd_en<=1'b0;end
end
//读写仲裁标志
always @(posedge clk or negedge rst_n)begin if(!rst_n)beginflag <=1'b0;end else if(wr_en&&rd_en &&state==IDLE)  begin // 同时接到读请求、写请求. flag<=~flag;endelse if(wr_en)begin   //突发一次写,flag<=1'b1;end else if(rd_en)begin   //突发一次读 flag<=1'b0;end
end//wr_en_out 传给端口模块的读写使能信号
//rd_en_outalways @(posedge clk or negedge rst_n)begin if(!rst_n)beginwr_en_out <=0 ; rd_en_out <=0 ;end else if( (wr_en_out||rd_en_out)&&state==ITFCEN)  beginwr_en_out <=0 ; rd_en_out <=0 ;endelse  if( state==ITFCEN)begin wr_en_out <=flag ; rd_en_out <=~flag ;end else beginwr_en_out <=0 ; rd_en_out <=0 ;end
end //**************************输出*********************************************/
//addr_iftc
always @(posedge clk or negedge rst_n)begin if(!rst_n)beginaddr_iftc <= 0;end else  if(flag==1'b0)beginaddr_iftc <= {rd_bank,addr_rd};end  else begin addr_iftc <= {wr_bank,addr_wr};end
end  //输出 时序
always @(posedge clk or negedge rst_n)begin if(!rst_n)begindout_fifo <= 0;dout_fifo_vld<=0;end else  begin dout_fifo <= din_ctrl;dout_fifo_vld<=din_ctrl_vld;end
end endmodule

SDRAM端口模块

SDRAM端口模块`include    "param.v"
module  sdram_itfc(input               clk         ,input               rst_n       ,input               wr_en       , //写使能 .同时地址数据有效input               rd_en       , //读使能input [23:0]        addr        ,  //12个地址加2个bank地址input       [15:0]  dout_sdram  ,   output      reg    dout_sdram_req , output              sclk        ,output  reg         cke         ,output              cs_n        ,  //除时钟外,使能型号output              ras_n       ,  //output              cas_n       ,  //output              we_n        ,  //output reg[1:0]     ba_addr     ,  //bank地址output reg[12:0]    sdram_addr  , //输进sdram地址//DQM maskoutput reg[1:0]     dqm_out     ,inout      [15:0]      dq       ,
//接控制模块    output reg[2:0]     done        ,    //反馈信号。地址反馈 及一个数据写完了反馈output reg[15:0]    data_ctrl   ,output reg          data_ctrl_vld );localparam  WAIT =8'b0000_0001, //上电等待20usPRECH=8'b0000_0010,//预充电AREF =8'b0000_0100,//刷新MRS  =8'b0000_1000,//模式设置IDLE =8'b0001_0000,//ACTI =8'b0010_0000,//bank+row激活  bank,block都是内部划分块名  WRITE=8'b0100_0000,//bank+列激活+写READ =8'b1000_0000;//bank+列激活+读reg  [3:0]      cmd;
reg  [7:0]      state;
reg  [7:0]      state_next;
wire            wait_prech ;
wire            prech_aref ;
wire            prech_idle ;
wire            aref_mrs   ;
wire            aref_idle  ;
wire            mrs_idle   ;
wire            idle_aref  ;
wire            idle_acti  ;
wire            acti_write ;
wire            acti_read  ;
wire            write_prech;
wire            read_prech ;
reg   [15:0]    cnt0;
wire            add_cnt0;
wire            end_cnt0;reg  [9:0]      cnt_ref;
reg             ref_flag;reg  [15:0]      max;   //每个状态cnt0计数最大值
reg              flag; //PRECH标志信号reg             wrrd_flag;
reg             data_vld_r0;  //CL为2的条件下
reg             data_vld_r1;
reg             data_vld_r2;  //列延时为3的情况下选wire [1:0]      bank;
wire [12:0]     row ;
wire [8:0]      col ;
reg            work;wire    [15:0]  dq_in           ;
reg    [15:0]  dq_out          ;
reg            dq_en           ;
assign  dq_in=dq;
assign  dq=dq_en?dq_out:16'bz;assign bank=addr[23:22];
assign row =addr[21:9] ;
assign col =addr[8:0]  ;always@(posedge  clk  or  negedge  rst_n )  beginif(!rst_n) beginstate<=WAIT;endelse beginstate<=state_next;end
end
always@(*)  begincase(state)WAIT  :beginif(wait_prech)  beginstate_next=PRECH;endelse beginstate_next=state;endend  PRECH :beginif( prech_aref)  beginstate_next=AREF;endelse if(prech_idle) beginstate_next=IDLE;endelse beginstate_next=state;endend   AREF  :beginif(aref_mrs)  beginstate_next=MRS;endelse if(aref_idle)  beginstate_next=IDLE;endelse beginstate_next=state;endend   MRS   :beginif(mrs_idle)  beginstate_next=IDLE;endelse beginstate_next=state;endend   IDLE  :beginif(idle_aref)  begin//优先state_next=AREF;endelse if(idle_acti)  beginstate_next=ACTI;endelse beginstate_next=state;endend   ACTI  :beginif(acti_write)  beginstate_next=WRITE;endelse if(acti_read)  beginstate_next=READ;endelse beginstate_next=state;endend   WRITE :beginif(write_prech)  beginstate_next=PRECH;endelse beginstate_next=state;endend   READ  :beginif(read_prech)  beginstate_next=PRECH;endelse beginstate_next=state;endend   default:state_next=IDLE;endcase
end
assign   wait_prech  = state== WAIT  && ( end_cnt0                   );
assign   prech_aref  = state== PRECH && (  flag==0 && end_cnt0       );
assign   prech_idle  = state== PRECH && (  flag==1 && end_cnt0       );
assign   aref_mrs    = state== AREF  && (  flag==0  && end_cnt0      );
assign   aref_idle   = state== AREF  && (  flag==1  && end_cnt0      );
assign   mrs_idle    = state== MRS   && ( end_cnt0                   );
assign   idle_aref   = state== IDLE  && ( ref_flag==1                );
assign   idle_acti   = state== IDLE  && ( work &&ref_flag==0         );  //ref_flag==1,done就不能发出信号,en就不能为1
assign   acti_write  = state== ACTI  && ( wrrd_flag==0 && end_cnt0   );
assign   acti_read   = state== ACTI  && ( wrrd_flag==1 && end_cnt0   );
assign   write_prech = state== WRITE && ( end_cnt0                   );  //数据写完后还要延迟2个clk
assign   read_prech  = state== READ  && ( end_cnt0                   );  //数据读完都可以立即发下一命令
//cnt_max
always@( * )  begincase(state)WAIT  :  max =`TIME_WAIT       ;  //20usPRECH :  max =`TIME_TRP        ;  //预充电20nsAREF  :  max =`TIME_TRC        ;  //刷新70nsMRS   :  max =`TIME_TMRS       ;  //模式寄存器2clkIDLE  :  max = 0               ;  //ACTI  :  max =`TIME_TRCD       ;  //激活行20ns//2WRITE :  max =(`BUSRT_MAX+2) ;  //突发长度完+2clk恢复周期 READ  :  max = `BUSRT_MAX      ;  //突发长度+0clk default:max =0;endcase
endalways@(posedge clk  or negedge rst_n)  beginif(!rst_n)  begincnt0<=0;endelse if(end_cnt0)  begincnt0<=0;endelse  if(add_cnt0)  begincnt0<=cnt0+1'b1;end
end
assign   add_cnt0=state!=IDLE ;
assign   end_cnt0=add_cnt0 && cnt0==max-1;//flag  //预充电下一状态标志//开机到idle后才开始计数
always@(posedge clk  or negedge rst_n)  beginif(!rst_n)  beginflag<=0;endelse if(mrs_idle)  beginflag<=1;    //第一次模式寄存器标志end
end
//cnt_ref;  //定时刷新标志
//ref_flag;
always@(posedge clk  or negedge rst_n)  beginif(!rst_n)  begincnt_ref<=0;endelse if(cnt_ref==`TIME_REF-1)  begin   //780周期cnt_ref<=1;endelse if( flag   )   begincnt_ref<=cnt_ref+1'b1;end
end
//刷新标志
always@(posedge clk  or negedge rst_n)  beginif(!rst_n)  beginref_flag<=0;endelse if(cnt_ref==`TIME_REF-1)  begin   //780周期ref_flag<=1;endelse  if(state==AREF)   beginref_flag<=0;end
end
//wrrd_flag  //读或者写标志
always@(posedge clk  or negedge rst_n)  beginif(!rst_n)  beginwrrd_flag<=0;endelse if(wr_en)  begin   //读写标志信号wrrd_flag<=0;endelse  if(rd_en)   beginwrrd_flag<=1;end
endalways @(posedge clk or negedge rst_n)begin if(!rst_n)beginwork <= 0;endelse if(state==ACTI)begin work <= 0;end else if( wr_en||rd_en  )begin work<=1'b1;end end//命令cmd
assign      cs_n = cmd[3]    ;
assign      ras_n= cmd[2]    ;
assign      cas_n= cmd[1]    ;
assign      we_n = cmd[0]    ;
always@(posedge clk  or negedge rst_n)  beginif(!rst_n)  begin  cmd<=4'b1111;endelse if(wait_prech) begin           //预充电 0010   同时外加  地址a10 为1cmd<=`CMD_PREC; //3endelse if(prech_aref)  begin              //刷新0001cmd<=`CMD_AREF;  //7endelse if(aref_mrs)  begin            //模式寄存器0000cmd<=`CMD_MRS; //2endelse if(idle_aref)  begin               //刷新0001cmd<=`CMD_AREF; //7endelse if(idle_acti)  begin                //激活行0011cmd<=`CMD_ACTI; //3endelse if(acti_write)  begin              //写 0100cmd<=`CMD_WRITE;  endelse if(acti_read)  begin               //读 0101cmd<=`CMD_RDAD; endelse if(read_prech||write_prech)  begin  //预充电0010cmd<=`CMD_PREC;    //同时外加  地址a10 为1endelse    begin     //空命令cmd<=`CMD_NOP; end
end// sclk//ckealways@(posedge clk  or negedge rst_n) beginif(!rst_n)  begincke<=0;endelse begincke<=1;endendassign  sclk=~clk;//~sclk延迟半个周期                       //ba_addr
//sdram_addr
always@(posedge clk  or negedge rst_n)  beginif(!rst_n)  begin  ba_addr <= 2'b00;sdram_addr<= 13'b0;endelse if(wait_prech||write_prech||read_prech)  begin     //预充电模式sdram_addr<=13'd1024;    //a10为1,所有预充电所有,不需要bank地址endelse if(aref_mrs)   beginba_addr <= 2'b00;sdram_addr<={ 3'b000 ,`OP , 2'b00 , `CAS_LTY , `BT , `BL};   //模式寄存器endelse if(idle_acti)  begin //激活ba_addr <= bank;//banksdram_addr<=row;   //行地址endelse if(acti_write||acti_read)  beginba_addr <= bank;//banksdram_addr<= col; //列地址end
end//done反馈信号
always@(*)  beginif(state!=IDLE||ref_flag ||work==1'b1 )  begin //780周期计数done=3'b100 ;   //正在工作中 ,不能给读写命令endelse  begindone=3'b000;end
end
//写数据
//dout_sdram_req
always@( posedge clk  or negedge rst_n )  beginif(!rst_n)   begindout_sdram_req<=0;endelse if(state==WRITE && cnt0==max-4) begindout_sdram_req<=0;   //提示下下个周期停止给写数据,数据时序输出,打一拍endelse  if(state== ACTI&&wrrd_flag==0 && add_cnt0 && cnt0==max-2)  begin  dout_sdram_req<=1'b1;  //提示下下个周期给写数据+列地址,数据时序输出,打一拍end
end
always@( posedge clk  or negedge rst_n )  beginif(!rst_n)   begindq_out<=0;endelse    begin  dq_out<=dout_sdram; end
end //读数据
always@(posedge clk  or negedge rst_n)  beginif(!rst_n)   begindata_vld_r0<=0;endelse   if(read_prech) begindata_vld_r0<=0;endelse  if(      acti_read    )  begin                               data_vld_r0<=1;  //突发写 ,经过CL列延迟个周期后,出数据end
end//组合输出
always@(*)  beginif(!rst_n)  begindata_ctrl=0;endelse  begindata_ctrl=dq_in;end
endalways@(posedge clk  or negedge rst_n)  begin  if(!rst_n)   begindata_ctrl_vld <=0;data_vld_r1<=0;endelse    begindata_vld_r1<=data_vld_r0;//data_vld_r2<=data_vld_r1;   //列延时为3的情况下选data_ctrl_vld<=data_vld_r1;end
end// dq_en /只在写的状态下拉高      always@(posedge clk  or negedge rst_n)  beginif(!rst_n)   begindq_en<=0;endelse  if(acti_write)  begin dq_en<=1;endelse   if(state==WRITE&&cnt0==max-3  ) begin    dq_en<=0;end
endalways@(posedge clk  or negedge rst_n)  beginif(!rst_n)   begindqm_out<=0;endelse   if(state==WRITE&&cnt0==max-3  ) begin          //写后要拉高dqm_outdqm_out<=2'b11;endelse if(state!=WRITE)  begindqm_out<=0;end
endendmodule 

VGA显示模块

VGA显示模块`include "param.v"
module  vga_itfc(input           clk     ,input           rst_n   ,input   [15:0]  din     ,input           din_vld ,  //数据有效output  reg     req     ,//请求数据信号output  reg [15:0]dout_rgb,output  reg     hsync   ,output  reg     vhync
);reg  [11:0]         cnt_h;   //行计数器
wire                add_cnt_h;
wire                end_cnt_h;reg  [9:0]          cnt_v;    //场计数器
wire                add_cnt_v;
wire                end_cnt_v;reg                 h_vld    ;  //行有效数据
reg                 v_vld    ;  //场有效数据reg                 rdreq       ;
wire                wrreq       ;
wire                empty       ;
wire                full        ;
wire  [15:0]        q           ;
wire  [9:0]         usedw       ;//    cnt_h  always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt_h <= 0;end else if(add_cnt_h)begin if(end_cnt_h)begin cnt_h <= 0;endelse begin cnt_h <= cnt_h + 1'b1;end endend assign add_cnt_h = 1'b1;   //上电即开始assign end_cnt_h = add_cnt_h && cnt_h ==`H_TP-1  ;  //1650always @(posedge clk or negedge rst_n)begin if(!rst_n)begincnt_v <= 0;end else if(add_cnt_v)begin if(end_cnt_v)begin cnt_v <= 0;endelse begin cnt_v <= cnt_v + 1'b1;end endend assign add_cnt_v = end_cnt_h;assign end_cnt_v = add_cnt_v && cnt_v == `V_TP-1;  //750
//h_vld行有效数据
always @(posedge clk or negedge rst_n)begin if(!rst_n)beginh_vld <= 0;end else if(add_cnt_h && cnt_h==(`H_SW+`H_BP-1) )begin   //h_vld<=1'b1; end else if(add_cnt_h&&cnt_h== (`H_SW +`H_BP +`H_AP-1) )begin h_vld<=0; end
end
//v_vld
always @(posedge clk or negedge rst_n)begin if(!rst_n)beginv_vld <= 0;end else if(add_cnt_v &&cnt_v== (`V_SW +`V_BP-1 ) )begin v_vld<=1'b1;end else if(add_cnt_v && cnt_v==(`V_SW +`V_BP +`V_AP-1) )begin v_vld<=0; end
end//rdreq
always @(   *  )begin  if( v_vld && h_vld && empty==0 )begin rdreq=1'b1;end else begin rdreq=0;  end
end
//dout_rgb
always @(* )begin if(!rst_n)begindout_rgb = 0;end else if( rdreq )begin dout_rgb=q;end else  begindout_rgb=0;end
end  //hsync
always @(posedge clk or negedge rst_n)begin if(!rst_n)beginhsync <= 0;end else if( add_cnt_h && cnt_h== `H_SW-1 )begin hsync<=1'b1;end else if(end_cnt_h)begin hsync<=0;end
end
//vhync
always @(posedge clk or negedge rst_n)begin if(!rst_n)beginvhync <= 0;end else if( add_cnt_v && cnt_v== `V_SW-1 )begin vhync<=1'b1;end else if(end_cnt_v)begin vhync<=0;end
end   buffer  u_buffer(.clock ( clk        ) ,.data  ( din        ) ,.rdreq ( rdreq      ) ,.wrreq ( wrreq      ) ,.empty ( empty      ) ,.full  ( full       ) ,.q     ( q          ) ,.usedw ( usedw      ) );//req向sdram读数据
always @(posedge clk or negedge rst_n)begin if(!rst_n)beginreq <= 0;end else if( usedw<200   )begin req<=1'b1;end else if(usedw>900)begin req<=0; end
end
assign  wrreq= (full==0) ? din_vld : 1'b0 ;endmodule 

参数模块


/**************************************sdram************************************/
//sdram工作参数//`define  BUSRT_1//`define  BUSRT_2//`define  BUSRT_4//`define  BUSRT_8`define  BUSRT_512    //突发长度`ifdef   BUSRT_1`define  BUSRT_MAX  1`define  BL   3'b000          //A0-A2`elsif  BUSRT_2`define  BUSRT_MAX  2`define  BL   3'b001`elsif  BUSRT_4`define  BUSRT_MAX  4`define  BL   3'b010`elsif  BUSRT_8`define  BUSRT_MAX  8`define  BL   3'b011`define  FIFO_L   300   //写FIFO的数量低值`define  FIFO_H   1500  //写FIFO的数量高值`elsif  BUSRT_512`define  BUSRT_MAX  512`define  BL   3'b111`define  FIFO_L   300   //写FIFO的数量低值`define  FIFO_H   1500  //写FIFO的数量高值`endif //连续突发//`define  BT   1      //A3`define  BT     1'b0//突发写/单写//`define  OP   1`define  OP     1'b0            //A9`define   CAS_LTY1  //列选  延迟//`define   CAS_LTY2`ifdef CAS_LTY1   //列选通延迟设置 延迟    A4-A6`define   CAS_LTY   3'b010`define    CL       2  `elsif CAS_LTY2`define   CAS_LTY   3'b011`define    CL       3  `endif`define   ADDR_MAX    16777215 //时间参数`define     TIME_TRC  7      //刷新命令生效时间  `define     TIME_TRP  3      //预充电时间`define     TIME_TMRS 2        //2个clk时钟周期  模式寄存器`define     TIME_WAIT  20000     //上电等待20us        `define     TIME_TRCD 3       //激活命令`define     TIME_REF  780     //自动刷新间隔 //cmd命令参数    cs_n使能,ras_n行选,cas_n列选,we_n写使能`define     CMD_WRITE 4'b0100   //写  `define     CMD_RDAD  4'b0101  //读`define     CMD_ACTI  4'b0011  //激活`define     CMD_NOP   4'b0111   //空操作`define     CMD_MRS   4'b0000  //模式寄存器`define     CMD_AREF  4'b0001  //自刷新  A10==1  `define     CMD_PREC  4'b0010   //预充电  所有bank  /**************************************图像采集模块************************************/
`define   ROW_MAX   720       //一共720行
`define   COL_MAX   2560    //一行1280个像素,一个像素2字节
`define   FPS       921600  //一帧数据有多少个数据     9216
`define   BUSRT_NUM 1800      //突发1800次,一帧数据完/**************************************vga端口模块************************************/
//vga端口模块  1280*720像素
`define     H_FP   110    //行前沿
`define     H_SW   40     //行同步脉冲
`define     H_BP   220    //行后沿
`define     H_AP   1280   //行有效像素
`define     H_TP   1650   //行总时序`define     V_FP   5      //场前沿
`define     V_SW   5      //场同步脉冲
`define     V_BP   20     //场后沿
`define     V_AP   720    //场有效像素
`define     V_TP   750    //场总时序     /**************************************I2C端口模块************************************/
//I2C端口模块
`define   CMD_EN   5'b000_01    //[0]表示为开始工作
`define   CMD_RDST 5'b000_10    //[1]表示发起始位
`define   CMD_WR   5'b001_00    //[2] 表示写数据
`define   CMD_RD   5'b010_00    //[3]表示接收数据
`define   CMD_NO   5'b100_00    //[4] 表示发送停止位不应答

备注:fifo_ctrl模块中调用了两个FIFO深度为1024,宽度一个为18bit(包含sop,eop),一个16bit;

VGA显示模块调用FIFO深度为1024,宽度为16bit;

另外调用pll生成时钟24M(摄像头配置输输出时钟)、75M(VGA显示模块输出时钟)、100M(SDRAM时钟)

基于intel(altera)FPGA OV5640摄像头 图像采集系统(完整代码)相关推荐

  1. STM32H750获取OV5640摄像头图像及上位机解码(一维码二维码)

    STM32H750获取OV5640摄像头图像及上位机解码(一维码&二维码) 1. 目的 针对静止拍摄图像场景,实现STM32H750对500万像素OV5640摄像头进行图像捕获,并通过串口将数 ...

  2. 煤炭价格预测:基于matlab的时间序列分析(主要流程+完整代码)

    基于matlab的时间序列分析(主要流程+完整代码) 案例简介 时间序列简介 平稳时间序列{xt} ARIMA=AR+MA+INTEGRATER 实例应用 数据平稳化 模型选择--确定p.q ACF/ ...

  3. 太空人时间HTML,基于JavaScript实现网红太空人表盘的完整代码

    一.效果展示 用javascript写的一个太空人表盘. 二.源代码 html代码 太空人表盘 function WatchMeter() { // 初始化dom this._initDom() // ...

  4. 基于intel x86+fpga智能驾驶舱和高级驾驶辅助系统硬件设计(二)

    系统功能架构及各模块功能介绍 智能驾驶舱和高级驾驶辅助系统是一个车载智能终端嵌入式平台,系统是一个能够运行 虚拟化操作系统的软件和硬件的综合体.本文的车载主机包括硬件主控处理器.电源管理芯 片.存储设 ...

  5. 飞思卡尔比赛K60驱动OLED12864显示摄像头采集的赛道图像,完整代码分享

    一.首先采集摄像头图像,由于硬件不同采集方式也不一样,我就不多做说明 二.将采集到的图像进行二值化 三.下面为完整显示函数 备注:大家主需要修改对应的引脚就行(修改初始化和宏定义) led.c文件 # ...

  6. 基于python的问答对联生成系统 附完整代码 毕业设计

    软件标题:智能对联生成系统 b 系统概述 使用项目:智能对联生成系统 软件用途:通过网页端可以获取到根据已有上联只能生成的下联. 开发历史:本项目未曾有前置版本.但在服务器搭建,Tensorflow ...

  7. 二分类问题:基于BERT的文本分类实践!附完整代码

    Datawhale 作者:高宝丽,Datawhale优秀学习者 寄语:Bert天生适合做分类任务.文本分类有fasttext.textcnn等多种方法,但在Bert面前,就是小巫见大巫了. 推荐评论展 ...

  8. 基于intel soc+fpga智能驾驶舱和高级驾驶辅助系统软件设计(三)

    虚拟化操作系统介绍 车载平台有逐渐融合的趋势,车载 SoC 的计算性能和应用快速增长,面临着多种应用在 多个显示子系统融合在一起的问题,这就要求平台运行多个操作系统.虚拟化(Virtualizatio ...

  9. XILINX FPGA OV5640 摄像头驱动(一)

    影像行业是一个值得深耕的方向,废话不多说 先看输入和输出 输入是光照,输出是光照的数字信号 image area:说的是感光矩阵,CMOS图像传感器的最核心部分,接收光照产生电信号的部分.决定了图像质 ...

最新文章

  1. ListBox滚动条置底
  2. 3G网络关闭,4G还会远吗?
  3. C#.NET通用权限管理在DB2数据库上运行的脚本参考 - 序列创建脚本参考
  4. java面试的基本问题_java面试常见基础问题之一
  5. string转map集合_[系列文章] Go - Map 集合
  6. ES6的 super 关键字
  7. oracle 常用故障,Oracle常见问题解决方案汇总
  8. .NET Core 3.0之深入源码理解HealthCheck(一)
  9. mac pip安装mysql_Mac pip安装mysql-python失败
  10. 您的浏览器由所属组织管理_FB频繁被封,关于多账号环境管理的知识你掌握了吗?...
  11. spring boot + vue + element-ui全栈开发入门——前端编辑数据对话框
  12. String 字符串问题一
  13. 【集群仿真】基于matlab固定翼无人机集群仿真演示平台【含Matlab源码 1497期】
  14. 时间序列R语言操作——非平稳时间序列变平稳
  15. android jni javah,JAVAH找不到类(android ndk)
  16. font-family
  17. 大数据平台架构有哪些
  18. 【网络通信 -- 直播】网络通信协议简介 -- RTP 协议的 H264 封包
  19. 手机内存如何快速自清理
  20. Linux command – Stressful Application Test

热门文章

  1. AI | 浅谈AI技术以及其今后发展
  2. speedoffice(PPT)怎么添加艺术字体
  3. 为什么显示芒果tv服务器异常怎么办,芒果TV显示MAC认证状态异常怎么办?
  4. 美团开放配送平台,争食即时配送业务
  5. Error while building/deploying project xxx
  6. 计算机科学与工程学院学位,山东科技大学-计算机科学与工程学院
  7. 思科双核心交换机双出口防火墙配置案例
  8. 新概念二册 Lesson 28 No parking禁止停车 ( 定语从句)
  9. 【2020·iSQE】峰会倒计时,日程抢先看!
  10. Linux命令之fdisk命令