赞
踩
此项目一共分为摄像头配置模块,图像采集模块,异步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) begin
- if(!rst_n) begin
- state<=WAIT;
- end
- else begin
- state<=state_next;
- end
- end
- always @(*)begin
- case(state)
- WAIT :begin
- if(wait_write) begin
- state_next=WRITE;
- end
- else begin
- state_next=WAIT;
- end
- end
- WRITE:begin
- if(write_idle) begin
- state_next=IDLE;
- end
- else begin
- state_next=WRITE;
- end
- end
- IDLE :begin
- state_next=IDLE;
- end
- default: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)begin
- cnt <= 0;
- end
- else if(add_cnt)begin
- if(end_cnt)begin
- cnt <= 0;
- end
- else 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)begin
- data_en <= 0;
- end
- else if( data_en==1 && state==WRITE ) begin
- data_en <= 0;
- end
- else 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)begin
- cnt_flag <= 0;
- end
- else if(data_en)begin
- cnt_flag<=1'b1;
- end
- else begin
- cnt_flag<=0;
- end
- end
- //lut_data
- always@(*)begin
- case( cnt ) //2个字节地址,一个字节数据
- //15fps VGA YUV output
- // 24MHz input clock, 24MHz PCLK
- 0 : 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 enable
- 5 : lut_data = {RW_CTRL,24'h3018_ff}; // D[5:0], GPIO[1:0] output enable
- 6 : lut_data = {RW_CTRL,24'h3034_1a}; // MIPI 10-bit
- 7 : 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 control
- 25 : lut_data = {RW_CTRL,24'h3601_33}; // VCM control
- 26 : lut_data = {RW_CTRL,24'h302d_60}; // system control
- 27 : 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.047x
- 31 : lut_data = {RW_CTRL,24'h3a18_00}; // gain ceiling
- 32 : lut_data = {RW_CTRL,24'h3a19_f8}; // gain ceiling = 15.5x
- 33 : 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 sum
- 39 : lut_data = {RW_CTRL,24'h3c05_98}; // threshold high sum
- 40 : 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 2
- 51 : lut_data = {RW_CTRL,24'h4005_1a}; // BLC always update
- 52 : lut_data = {RW_CTRL,24'h3000_00}; // enable blocks
- 53 : lut_data = {RW_CTRL,24'h3004_ff}; // enable clocks
- 54 : lut_data = {RW_CTRL,24'h300e_58}; // MIPI power down, DVP enable
- 55 : 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 RGB
- 58 : 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 high
- 61 : lut_data = {RW_CTRL,24'h3a10_28}; // stable range in low
- 62 : lut_data = {RW_CTRL,24'h3a1b_30}; // stable range out high
- 63 : lut_data = {RW_CTRL,24'h3a1e_26}; // stable range out low
- 64 : lut_data = {RW_CTRL,24'h3a11_60}; // fast zone high
- 65 : 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 block
- 129: lut_data = {RW_CTRL,24'h5181_f2}; // AWB control
- 130: lut_data = {RW_CTRL,24'h5182_00}; // [7:4] max local counter, [3:0] max fast counter
- 131: lut_data = {RW_CTRL,24'h5183_14}; // AWB advanced
- 132: 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 limit
- 146: lut_data = {RW_CTRL,24'h5192_04}; // AWB bottom limit
- 147: lut_data = {RW_CTRL,24'h5193_70}; // red limit
- 148: lut_data = {RW_CTRL,24'h5194_f0}; // green limit
- 149: lut_data = {RW_CTRL,24'h5195_f0}; // blue limit
- 150: lut_data = {RW_CTRL,24'h5196_03}; // AWB control
- 151: lut_data = {RW_CTRL,24'h5197_01}; // local limit
- 152: 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 Y
- 177: lut_data = {RW_CTRL,24'h5382_5b}; // CMX2 for Y
- 178: lut_data = {RW_CTRL,24'h5383_08}; // CMX3 for Y
- 179: lut_data = {RW_CTRL,24'h5384_0a}; // CMX4 for U
- 180: lut_data = {RW_CTRL,24'h5385_7e}; // CMX5 for U
- 181: lut_data = {RW_CTRL,24'h5386_88}; // CMX6 for U
- 182: lut_data = {RW_CTRL,24'h5387_7c}; // CMX7 for V
- 183: lut_data = {RW_CTRL,24'h5388_6c}; // CMX8 for V
- 184: lut_data = {RW_CTRL,24'h5389_10}; // CMX9 for V
- 185: 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 1
- 195: lut_data = {RW_CTRL,24'h5301_30}; // CIP sharpen MT threshold 2
- 196: lut_data = {RW_CTRL,24'h5302_10}; // CIP sharpen MT offset 1
- 197: lut_data = {RW_CTRL,24'h5303_00}; // CIP sharpen MT offset 2
- 198: lut_data = {RW_CTRL,24'h5304_08}; // CIP DNS threshold 1
- 199: lut_data = {RW_CTRL,24'h5305_30}; // CIP DNS threshold 2
- 200: lut_data = {RW_CTRL,24'h5306_08}; // CIP DNS offset 1
- 201: lut_data = {RW_CTRL,24'h5307_16}; // CIP DNS offset 2
- 202: lut_data = {RW_CTRL,24'h5309_08}; // CIP sharpen TH threshold 1
- 203: lut_data = {RW_CTRL,24'h530a_30}; // CIP sharpen TH threshold 2
- 204: lut_data = {RW_CTRL,24'h530b_04}; // CIP sharpen TH offset 1
- 205: lut_data = {RW_CTRL,24'h530c_06}; // CIP sharpen TH offset 2
- 206: 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 84Mhz
- 208: lut_data = {RW_CTRL,24'h3035_21}; // PLL
- 209: lut_data = {RW_CTRL,24'h3036_69}; // PLL
- 210: lut_data = {RW_CTRL,24'h3c07_07}; // lightmeter 1 threshold[7:0]
- 211: lut_data = {RW_CTRL,24'h3820_47}; // flip
- 212: lut_data = {RW_CTRL,24'h3821_01}; // no mirror
- 213: lut_data = {RW_CTRL,24'h3814_31}; // timing X inc
- 214: lut_data = {RW_CTRL,24'h3815_31}; // timing Y inc
- 215: lut_data = {RW_CTRL,24'h3800_00}; // HS
- 216: lut_data = {RW_CTRL,24'h3801_00}; // HS
- 217: lut_data = {RW_CTRL,24'h3802_00}; // VS
- 218: lut_data = {RW_CTRL,24'h3803_fa}; // VS
- 219: 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 1280
- 224: lut_data = {RW_CTRL,24'h3809_00}; // DVPHO
- 225: lut_data = {RW_CTRL,24'h380a_02}; // DVPVO 720
- 226: lut_data = {RW_CTRL,24'h380b_d0}; // DVPVO
- 227: lut_data = {RW_CTRL,24'h380c_07}; // HTS
- 228: lut_data = {RW_CTRL,24'h380d_64}; // HTS
- 229: lut_data = {RW_CTRL,24'h380e_02}; // VTS
- 230: lut_data = {RW_CTRL,24'h380f_e4}; // VTS
- 231: lut_data = {RW_CTRL,24'h3813_04}; // timing V offset
- 232: 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 exposure
- 237: lut_data = {RW_CTRL,24'h3a03_e0}; // 60Hz max exposure
- 238: lut_data = {RW_CTRL,24'h3a14_02}; // 50Hz max exposure
- 239: lut_data = {RW_CTRL,24'h3a15_e0}; // 50Hz max exposure
- 240: lut_data = {RW_CTRL,24'h4004_02}; // BLC line number
- 241: lut_data = {RW_CTRL,24'h3002_1c}; // reset JFIFO, SFIFO, JPG
- 242: lut_data = {RW_CTRL,24'h3006_c3}; // disable clock of JPEG2x, JPEG
- 243: lut_data = {RW_CTRL,24'h4713_03}; // JPEG mode 3
- 244: lut_data = {RW_CTRL,24'h4407_04}; // Quantization scale
- 245: 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 timing
- 248: lut_data = {RW_CTRL,24'h3824_04}; // PCLK manual divider
- 249: lut_data = {RW_CTRL,24'h5001_83}; // SDE on, CMX on, AWB on
- 250: 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;
- endcase
- end
- endmodule

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) begin
- if(!rst_n) begin
- state<=IDLE;
- end
- else begin
- state<=state_next;
- end
- end
- always@(*) begin
- case(state)
- IDLE : begin
- if(idle_start) begin
- state_next=START;
- end
- else begin
- state_next<=state;
- end
- end
- START: begin
- if(start_write) begin
- state_next=WRITE;
- end
- else begin
- state_next<=state;
- end
- end
- WRITE: begin
- if(write_actack) begin
- state_next=ACTACK;
- end
- else begin
- state_next<=state;
- end
- end
- ACTACK: begin
- if(actack_start) begin
- state_next=START;
- end
- else if(actack_write) begin
- state_next=WRITE;
- end
- else if(actack_read) begin
- state_next=READ;
- end
- else if(actack_stop) begin
- state_next=STOP;
- end
- else begin
- state_next<=state;
- end
- end
- READ : begin
- if(read_sendack) begin
- state_next=SENDACK;
- end
- else begin
- state_next<=state;
- end
- end
- SENDACK: begin
- if(sendack_stop) begin
- state_next=STOP;
- end
- else if(sendack_read) begin
- state_next=READ;
- end
- else begin
- state_next<=state;
- end
- end
- STOP : begin
- if(stop_idle) begin
- state_next=IDLE;
- end
- else begin
- state_next<=state;
- end
- end
- default: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) begin
- if(!rst_n) begin
- cnt_bit<=0;
- end
- else if(end_cnt_bit) begin
- cnt_bit<=0;
- end
- else if(add_cnt_bit) begin
- cnt_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) begin
- if(!rst_n) begin
- cnt_byte<=0;
- end
- else if(end_cnt_byte) begin
- cnt_byte<=0;
- end
- else if(add_cnt_byte) begin
- cnt_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@( * ) begin
- if(!rst_n) begin
- max=0;
- end
- else begin
- case(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) begin
- if(!rst_n) begin
- scl<=1;
- end
- else if( cnt_bit==DOW_TIME-1 ) begin //
- scl<=1;
- end
- else if( start_write|| ( (state==WRITE||state==READ||state==ACTACK||state==SENDACK)&&cnt_bit==PAN-1&&actack_stop==0 ) ) begin
- scl<=0; //数据传输状态scl先低电平再高电平
- end
- else if(state==START ||state==STOP) begin //起始状态,stop状态高电平
- scl<=1;
- end
- end
- //ack
- always@(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- ack<=0;
- end
- else if(state==ACTACK && cnt_bit==RD_TIME) begin
- ack<=sda_in; //发数据时,反馈ack是否应答
- end
- else if( stop_idle ) begin //一次数据发送结束,反馈一个信号
- ack<=1;
- end
- else begin
- ack<=0;
- end
- end
- //sda_en
- always@(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- sda_en<=1;
- end
- else if(actack_read||write_actack||sendack_read) begin //接收应答信号 和 读数据时候 为低电平
- sda_en<=0;
- end
- else if( read_sendack ||actack_start||actack_write||actack_stop) begin
- sda_en<=1;
- end
- end
- //sda_out
- always@(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- sda_out<=1; //空闲为1
- end
- else if(state==START&& cnt_bit==DOW_TIME ) begin //起始状态,sda由高拉低
- sda_out<=0;
- end
- else if(state==WRITE && cnt_bit==WR_TIME ) begin //写数据状态,scl低电平写数据
- sda_out<=wr_din[7-cnt_byte]; //高字节先发
- end
- else if(read_sendack&&cmd==`CMD_NO) begin //发送应答信号状态, NO_ACK
- sda_out<=1;
- end
- else if( read_sendack ) begin //发送应答信号状态,ACK
- sda_out<=0;
- end
- else if( actack_stop|| sendack_stop ) begin //停止状态先拉低
- sda_out<=0;
- end
- else if( state==STOP && cnt_bit==DOW_TIME ) begin //停止状态又由低拉高
- sda_out<=1;
- end
- end
- //sda_in data_flag
- always@(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- data_flag<=0;
- end
- else 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) begin
- if(!rst_n) begin
- done0<=0;
- end
- else if( ((state==ACTACK|| state==READ )&&cnt_bit==PAN-4 && cnt_byte==max-1)||stop_idle) begin
- //done信号提前3个周期给出去,或者状态结束(反馈到控制模块)
- done0<=1;
- end
- else begin
- done0<=0;
- end
- end
- //rd_out rd_out_vld
- always@(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- rd_out<=0;
- rd_out_vld<=0;
- end
- else if( state==READ &&cnt_bit==PAN-1 ) begin
- rd_out<=data_flag;
- rd_out_vld<=1;
- end
- else begin
- rd_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, //摄像头写ID
- RD_ID =8'h79; //摄像头读ID
-
- reg [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)begin
- data_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) begin
- if(!rst_n) begin
- per<=0;
- wr_rd<=0; //0代表读,1代表写
- end
- else if( rw_ctrl==1 && data_en ) begin //写模式+读模式
- per<=2;
- wr_rd<=1;
- end
- else if(rw_ctrl==0 && data_en) begin //只写模式
- per<=1;
- wr_rd<=1;
- end
- else if(cnt_byte==MAX && ack==1) begin //ack只有一个周期
- per<=per-1'b1;
- wr_rd<=0; //读数据
- end
- end
- //redy
- always@(* ) begin
- if( per==0 ) begin //per==1 代表空闲状态
- redy=1'b1 ;
- end
- else begin
- redy=0 ;
- end
- end
- //no_ack
- always@(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- no_ack<=0;
- end
- else if(cnt_byte>0&&cnt_byte<MAX) begin
- no_ack<=ack;
- end
- else begin
- no_ack<=0;
- end
- end
- //cnt_byte
- always@(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- cnt_byte<=0;
- end
- else if(end_cnt_byte && ack==1) begin
- cnt_byte<=0;
- end
- else if(end_cnt_byte ) begin
- cnt_byte<=cnt_byte;
- end
- else if(add_cnt_byte) begin
- cnt_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) begin
- if(!rst_n) begin
- MAX<=0;
- end
- else if(wr_rd==1 && cnt_byte==0) begin
- MAX<=WR_NUM ;
- end
- else if(wr_rd==0 && cnt_byte==0 ) begin
- MAX<=RD_NUM ;
- end
- end
- //输出给端口模块数据data_i2c
- always@(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- data_i2c<=0;
- cmd<=0;
- end
- else if( wr_rd==1 ) begin //write
- if( (per==1 ||per==2)&&cnt_byte==0 ) begin //写模式
- cmd<=`CMD_EN; //端口模块开始工作
- data_i2c<=WR_ID;
- end
- else
- 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 :begin
- cmd<=`CMD_NO;
- end
- default:data_i2c<=0;
- endcase
- end
- else if( wr_rd==0 ) begin //read
- if( (per==1 ||per==2)&&cnt_byte==0 ) begin
- cmd<=`CMD_EN; //端口模块开始工作
- data_i2c<=WR_ID;
- end
- else
- 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<=RD_ID;
- cmd<=`CMD_RDST;
- end
- 4 :begin
- cmd<=`CMD_RD;
- end
- 5 :begin
- cmd<=`CMD_NO;
- end
- default:begin
- data_i2c<=0;
- cmd<=0;
- end
- endcase
- end
- end
- assign 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) begin
- if(!rst_n) begin
- vsync_r<=0;
- end
- else if( vsync && config_done) begin //摄像头配置完成
- vsync_r<=1'b1 ;
- end
- else if(dout_vld) begin
- vsync_r<=0;
- end
- end
- always @(posedge clk or negedge rst_n)begin
- if(!rst_n)begin
- href_flag <= 0;
- end
- else if(dout_lvd_en) begin
- href_flag<=0;
- end
- else 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)begin
- cnt_col <= 0;
- end
- else if(add_cnt_col)begin
- if(end_cnt_col)begin
- cnt_col <= 0;
- end
- else 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)begin
- cnt_row <= 0;
- end
- else if(add_cnt_row)begin
- if(end_cnt_row)begin
- cnt_row <= 0;
- end
- else 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; //720
-
- always @(posedge clk or negedge rst_n)begin
- if(!rst_n) begin
- dout<=0;
- end
- else begin
- dout[15-cnt_col[0]*8 -:8] <= din;
- end
- end
- //dout_vld 数据晚一个周期
- always @(posedge clk or negedge rst_n)begin
- if(!rst_n) begin
- dout_vld<=0;
- end
- else 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)begin
- sop <= 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)begin
- dout_lvd_en <= 0;
- end
- else if(eop)begin
- dout_lvd_en<=1'b1;
- end
- else if( vsync )begin
- dout_lvd_en<=1'b0;
- end
- end
-
- //仿真测试用
- always@(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- cnt_dout_vld<=0;
- end
- else if(eop) begin
- cnt_dout_vld<=0;
- end
- else if( add_cnt_col && dout_vld==1'b1) begin
- cnt_dout_vld<=cnt_dout_vld+1'b1;
- end
-
- end
-
- endmodule
-
-

异步FIFO控制模块
此模块采用FIFO18位宽:数据+sop+eop判断
- //异步FIFO处理跨时域问题,判断是否丢帧问题
- `include "param.v"
- //wrfifo 18位
- //rdfifo 16位
- module fifo_ctrl (
- input clk , //100m
- input rst_n ,
- input clk_in , //84m
- input 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)begin
- wrfifo_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;
- end
- end
- always @( * )begin
- if(sop_vld )begin
- rdreq_flag=1'b1;
- end
- else begin
- rdreq_flag = wrfifo_rdreq;
- end
- end
- always @(posedge clk or negedge rst_n)begin
- if(!rst_n)begin
- cnt_num <= 0;
- end
- else if(wrfifo_qout[16]) begin
- cnt_num<=0;
- end
- else if(sop_vld==0 &&rdreq_flag )begin
- cnt_num<=cnt_num+1'b1;
- end
- end
- assign wrfifo_q=(sop_vld==0)?wrfifo_qout:0;
-
- always @(posedge clk_in or negedge rst_n)begin
- if(!rst_n)begin
- sop_flag <= 0;
- end
- else if(sop==1'b1)begin
- sop_flag<=1'b1;
- end
- else if(eop)begin
- sop_flag <= 0;
- end
- end
- always @(posedge clk_in or negedge rst_n)begin
- if(!rst_n)begin
- wrfifo_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)begin
- cnt_vld <= 0;
- end
- else if(sop_flag==0) begin
- cnt_vld<=0;
- end
- else 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) begin
- if(!rst_n) begin
- data_vga<=0;
- data_vga_vld<=0;
- end
- else begin
- data_vga<=rdfifo_q;
- data_vga_vld<=rdfifo_rdreq;
- end
- end
- assign 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)begin
- sop<=0;
- eop<=0;
- end
- else if(state==WRITE||write_idle) begin
- eop<=wrfifo_seop[0];
- sop<=0;
- end
- else if(addr_write ) begin
- sop<=wrfifo_seop[1];
- eop<=0;
- end
- else begin
- sop<=0;
- eop<=0;
- end
- end
- //**************************状态机**********************************************/
- always @(posedge clk or negedge rst_n)begin
- if(!rst_n)begin
- state <= IDLE;
- end
- else begin
- state <= state_next;
- end
- end
- always @(*)begin
- case(state)
- IDLE :begin
- if(idle_itfcen) begin
- state_next=ITFCEN;
- end
- else begin
- state_next=state;
- end
- end
- ITFCEN :begin
- if(itfcen_addr) begin
- state_next=ADDR;
- end
- else begin
- state_next=state;
- end
- end
- ADDR: begin
- if(addr_write) begin
- state_next=WRITE;
- end
- else if(addr_read) begin
- state_next=READ;
- end
- else begin
- state_next=state;
- end
- end
- WRITE:begin
- if(write_idle) begin
- state_next=IDLE;
- end
- else begin
- state_next=state;
- end
- end
- READ :begin
- if(read_idle) begin
- state_next=IDLE;
- end
- else begin
- state_next=state;
- end
- end
- default: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)begin
- addr_wr <=1'b0;
- end
- else if(add_addr_wr)begin
- if(end_addr_wr)begin
- addr_wr <=1'b0;
- end
- else 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)begin
- addr_rd <=1'b0;
- end
- else if(add_addr_rd)begin
- if(end_addr_rd)begin
- addr_rd <=1'b0;
- end
- else 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)begin
- seop <= 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)begin
- wr_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 ) begin
- bank_turn<=1'b1; //翻转后
- end
- end
- //bank_flag 第一个bank写完标志
-
- //*****************************突发信号******************************/
- always @(posedge clk or negedge rst_n)begin
- if(!rst_n)begin
- sop_vld_r0 <=1'b0;
- sop_vld_r1 <=1'b0;
- end
- else begin //
- sop_vld_r0 <=sop_vld;
- sop_vld_r1 <=sop_vld_r0;
- end
- end
- assign 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)begin
- sop_flag <=1'b0;
- end
- else if(pedge) begin
- sop_flag<=1'b1;
- end
- else if(nedge) begin
- sop_flag<=1'b0;
- end
- end
- always @(posedge clk or negedge rst_n)begin
- if(!rst_n)begin
- wr_en <=1'b0;
- end
- else if(idle_itfcen) begin
- wr_en<=1'b0;
- end
- else 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)begin
- rd_en <=1'b0;
- end
- else if(idle_itfcen) begin
- rd_en <=1'b0;
- end
- else 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)begin
- flag <=1'b0;
- end
- else if(wr_en&&rd_en &&state==IDLE) begin // 同时接到读请求、写请求.
- flag<=~flag;
- end
- else if(wr_en)begin //突发一次写,
- flag<=1'b1;
- end
- else if(rd_en)begin //突发一次读
- flag<=1'b0;
- end
- end
-
- //wr_en_out 传给端口模块的读写使能信号
- //rd_en_out
-
- always @(posedge clk or negedge rst_n)begin
- if(!rst_n)begin
- wr_en_out <=0 ;
- rd_en_out <=0 ;
- end
- else if( (wr_en_out||rd_en_out)&&state==ITFCEN) begin
- wr_en_out <=0 ;
- rd_en_out <=0 ;
- end
- else if( state==ITFCEN)begin
- wr_en_out <=flag ;
- rd_en_out <=~flag ;
- end
- else begin
- wr_en_out <=0 ;
- rd_en_out <=0 ;
- end
- end
-
- //**************************输出*********************************************/
- //addr_iftc
- always @(posedge clk or negedge rst_n)begin
- if(!rst_n)begin
- addr_iftc <= 0;
- end
- else if(flag==1'b0)begin
- addr_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)begin
- dout_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 mask
- output 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, //上电等待20us
- PRECH=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 ) begin
- if(!rst_n) begin
- state<=WAIT;
- end
- else begin
- state<=state_next;
- end
- end
- always@(*) begin
- case(state)
- WAIT :begin
- if(wait_prech) begin
- state_next=PRECH;
- end
- else begin
- state_next=state;
- end
- end
- PRECH :begin
- if( prech_aref) begin
- state_next=AREF;
- end
- else if(prech_idle) begin
- state_next=IDLE;
- end
- else begin
- state_next=state;
- end
- end
- AREF :begin
- if(aref_mrs) begin
- state_next=MRS;
- end
- else if(aref_idle) begin
- state_next=IDLE;
- end
- else begin
- state_next=state;
- end
- end
- MRS :begin
- if(mrs_idle) begin
- state_next=IDLE;
- end
- else begin
- state_next=state;
- end
- end
- IDLE :begin
- if(idle_aref) begin//优先
- state_next=AREF;
- end
- else if(idle_acti) begin
- state_next=ACTI;
- end
- else begin
- state_next=state;
- end
- end
- ACTI :begin
- if(acti_write) begin
- state_next=WRITE;
- end
- else if(acti_read) begin
- state_next=READ;
- end
- else begin
- state_next=state;
- end
- end
- WRITE :begin
- if(write_prech) begin
- state_next=PRECH;
- end
- else begin
- state_next=state;
- end
- end
- READ :begin
- if(read_prech) begin
- state_next=PRECH;
- end
- else begin
- state_next=state;
- end
- end
- 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@( * ) begin
- case(state)
- WAIT : max =`TIME_WAIT ; //20us
- PRECH : max =`TIME_TRP ; //预充电20ns
- AREF : max =`TIME_TRC ; //刷新70ns
- MRS : max =`TIME_TMRS ; //模式寄存器2clk
- IDLE : max = 0 ; //
- ACTI : max =`TIME_TRCD ; //激活行20ns//2
- WRITE : max =(`BUSRT_MAX+2) ; //突发长度完+2clk恢复周期
- READ : max = `BUSRT_MAX ; //突发长度+0clk
- default:max =0;
- endcase
- end
- always@(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- cnt0<=0;
- end
- else if(end_cnt0) begin
- cnt0<=0;
- end
- else if(add_cnt0) begin
- cnt0<=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) begin
- if(!rst_n) begin
- flag<=0;
- end
- else if(mrs_idle) begin
- flag<=1; //第一次模式寄存器标志
- end
- end
- //cnt_ref; //定时刷新标志
- //ref_flag;
- always@(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- cnt_ref<=0;
- end
- else if(cnt_ref==`TIME_REF-1) begin //780周期
- cnt_ref<=1;
- end
- else if( flag ) begin
- cnt_ref<=cnt_ref+1'b1;
- end
- end
- //刷新标志
- always@(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- ref_flag<=0;
- end
- else if(cnt_ref==`TIME_REF-1) begin //780周期
- ref_flag<=1;
- end
- else if(state==AREF) begin
- ref_flag<=0;
- end
- end
- //wrrd_flag //读或者写标志
- always@(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- wrrd_flag<=0;
- end
- else if(wr_en) begin //读写标志信号
- wrrd_flag<=0;
- end
- else if(rd_en) begin
- wrrd_flag<=1;
- end
- end
- always @(posedge clk or negedge rst_n)begin
- if(!rst_n)begin
- work <= 0;
- end
- else 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) begin
- if(!rst_n) begin
- cmd<=4'b1111;
- end
- else if(wait_prech) begin //预充电 0010 同时外加 地址a10 为1
- cmd<=`CMD_PREC; //3
- end
- else if(prech_aref) begin //刷新0001
- cmd<=`CMD_AREF; //7
- end
- else if(aref_mrs) begin //模式寄存器0000
- cmd<=`CMD_MRS; //2
- end
- else if(idle_aref) begin //刷新0001
- cmd<=`CMD_AREF; //7
- end
- else if(idle_acti) begin //激活行0011
- cmd<=`CMD_ACTI; //3
- end
- else if(acti_write) begin //写 0100
- cmd<=`CMD_WRITE;
- end
- else if(acti_read) begin //读 0101
- cmd<=`CMD_RDAD;
- end
- else if(read_prech||write_prech) begin //预充电0010
- cmd<=`CMD_PREC; //同时外加 地址a10 为1
- end
- else begin //空命令
- cmd<=`CMD_NOP;
- end
- end
-
- // sclk
- //cke
- always@(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- cke<=0;
- end
- else begin
- cke<=1;
- end
- end
- assign sclk=~clk;//~sclk延迟半个周期
- //ba_addr
- //sdram_addr
- always@(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- ba_addr <= 2'b00;
- sdram_addr<= 13'b0;
- end
- else if(wait_prech||write_prech||read_prech) begin //预充电模式
- sdram_addr<=13'd1024; //a10为1,所有预充电所有,不需要bank地址
- end
- else if(aref_mrs) begin
- ba_addr <= 2'b00;
- sdram_addr<={ 3'b000 ,`OP , 2'b00 , `CAS_LTY , `BT , `BL}; //模式寄存器
- end
- else if(idle_acti) begin //激活
- ba_addr <= bank;//bank
- sdram_addr<=row; //行地址
- end
- else if(acti_write||acti_read) begin
- ba_addr <= bank;//bank
- sdram_addr<= col; //列地址
- end
- end
- //done反馈信号
- always@(*) begin
- if(state!=IDLE||ref_flag ||work==1'b1 ) begin //780周期计数
- done=3'b100 ; //正在工作中 ,不能给读写命令
- end
- else begin
- done=3'b000;
- end
- end
- //写数据
- //dout_sdram_req
- always@( posedge clk or negedge rst_n ) begin
- if(!rst_n) begin
- dout_sdram_req<=0;
- end
- else if(state==WRITE && cnt0==max-4) begin
- dout_sdram_req<=0; //提示下下个周期停止给写数据,数据时序输出,打一拍
- end
- else 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 ) begin
- if(!rst_n) begin
- dq_out<=0;
- end
- else begin
- dq_out<=dout_sdram;
- end
- end
- //读数据
- always@(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- data_vld_r0<=0;
- end
- else if(read_prech) begin
- data_vld_r0<=0;
- end
- else if( acti_read ) begin
- data_vld_r0<=1; //突发写 ,经过CL列延迟个周期后,出数据
- end
- end
- //组合输出
- always@(*) begin
- if(!rst_n) begin
- data_ctrl=0;
- end
- else begin
- data_ctrl=dq_in;
- end
- end
- always@(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- data_ctrl_vld <=0;
- data_vld_r1<=0;
- end
- else begin
- data_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) begin
- if(!rst_n) begin
- dq_en<=0;
- end
- else if(acti_write) begin
- dq_en<=1;
- end
- else if(state==WRITE&&cnt0==max-3 ) begin
- dq_en<=0;
- end
- end
- always@(posedge clk or negedge rst_n) begin
- if(!rst_n) begin
- dqm_out<=0;
- end
- else if(state==WRITE&&cnt0==max-3 ) begin //写后要拉高dqm_out
- dqm_out<=2'b11;
- end
- else if(state!=WRITE) begin
- dqm_out<=0;
- end
- end
-
-
- endmodule

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)begin
- cnt_h <= 0;
- end
- else if(add_cnt_h)begin
- if(end_cnt_h)begin
- cnt_h <= 0;
- end
- else begin
- cnt_h <= cnt_h + 1'b1;
- end
- end
- end
- assign add_cnt_h = 1'b1; //上电即开始
- assign end_cnt_h = add_cnt_h && cnt_h ==`H_TP-1 ; //1650
-
- always @(posedge clk or negedge rst_n)begin
- if(!rst_n)begin
- cnt_v <= 0;
- end
- else if(add_cnt_v)begin
- if(end_cnt_v)begin
- cnt_v <= 0;
- end
- else begin
- cnt_v <= cnt_v + 1'b1;
- end
- end
- end
- 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)begin
- h_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)begin
- v_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)begin
- dout_rgb = 0;
- end
- else if( rdreq )begin
- dout_rgb=q;
- end
- else begin
- dout_rgb=0;
- end
- end
-
- //hsync
- always @(posedge clk or negedge rst_n)begin
- if(!rst_n)begin
- hsync <= 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)begin
- vhync <= 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)begin
- req <= 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时钟)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。