一、为什么要用Serdes
空间过采样法实现思路
https://blog.csdn.net/wudinin/article/details/101720274
没落骑士
https://www.cnblogs.com/moluoqishi/p/9049243.html
https://blog.csdn.net/yijingjijng/article/details/48024059
https://www.cnblogs.com/limanjihe/p/9889524.html
https://blog.csdn.net/wudinin/article/details/101720274
https://blog.csdn.net/qq_39731597/article/details/131021578
代码
https://download.csdn.net/download/anjoid/4291664

1 //高速串行数字接口数据恢复模块Verilog代码 2 3 /* 4 Anjoid 2012.4.27 5 6 输入4个相位差各为45度的时钟,频率为串行数据流最高频率的一半 7 1010 1010为起始bit流,DataAvbl有效,随后在ByteEn的上升或下降沿读取连续输出字节,遇到14个0则结束此次通信,DataAvbl清零 8 发送bit流的字节MSB在前 9 需要发送端对连0和连1进行扰码 要求在出现连续10个0或者10个1时 插入一个相反的bit 本模块对接收到的bit流进行解扰判别,将连续10个0或1后面跟着的反位抛弃 10 */ 11 12 module DSI(nRst,clk0,clk45,clk90,clk135,bitIn,ByteOut,ByteWR,DataAvbl); 13 input nRst,clk0,clk45,clk90,clk135,bitIn; //复位 4个相位差各45度的时钟 串行输入数据流 14 output ByteOut; //经过解扰最终输出的字节 15 output ByteWR; //字节输出写脉冲 高电平时读取ByteOut数据 16 output DataAvbl; //传输有效信号 高电平表示传输正在进行 17 18 19 reg[3:0] f4b,b4b;//采样bit缓冲 前后各4个bit 20 reg[7:0] samplebits,bits2read,transpzn;//bit采样寄存器 跳变沿位置对应数据 采样跳变沿寄存器 21 reg[8:0] bitbuffer; //bit暂存对比寄存器 22 23 reg[3:0] transvct[7:0];//采样位置循环向量寄存器 24 reg[7:0] vcttemp; //采样位置寄存器 25 26 reg[3:0] vctcount;// 向量循环判定用计数器 27 28 reg[7:0] samplebyte,bytebuffer;//串并转换得到的字节,更新待输出的字节 29 reg[3:0] bitcount;//串行bit计数器 30 reg[3:0] judgestate,zerocount,onecount;//bit流判决状态 连续0个数计数器 连续1个数计数器 31 32 33 reg[7:0] ByteOut; //输出字节 34 reg ByteWR; //输出字节写脉冲 35 reg beginen;//输出首字节屏蔽标示 36 wire DataAvbl; //通信有效 37 38 assign DataAvbl = judgestate[3]; //状态机在8的时候 传输有效 39 40 /* 41 分别在4个时钟上下沿,对两个bit做共8次采样 42 */ 43 always @ (posedge clk0) 44 begin 45 samplebits[7] <= bitIn; 46 f4b[3:0] <= samplebits[7:4]; //将前四个采样暂存 47 end 48 always @ (posedge clk45) 49 begin 50 samplebits[6] <= bitIn; 51 end 52 always @ (posedge clk90) 53 begin 54 samplebits[5] <= bitIn; 55 end 56 always @ (posedge clk135) 57 begin 58 samplebits[4] <= bitIn; 59 end 60 61 always @ (negedge clk0) 62 begin 63 samplebits[3] <= bitIn; 64 b4b[3:0] <= samplebits[3:0]; //将后四位采样暂存 65 end 66 always @ (negedge clk45) 67 begin 68 samplebits[2] <= bitIn; 69 end 70 always @ (negedge clk90) 71 begin 72 samplebits[1] <= bitIn; 73 end 74 always @ (negedge clk135) 75 begin 76 samplebits[0] <= bitIn; 77 end 78 79 80 always @ (posedge clk0) 81 begin 82 bitbuffer[7:0] <= {f4b[3:0],b4b[3:0]}; // 83 bitbuffer[8] <= bitbuffer[0]; //上一次采样最后1bit放在最高位 用于在下一时钟判断前后bit是否有异或情况 84 end 85 86 always @ (posedge clk0) 87 begin 88 if(!nRst) 89 begin 90 transpzn=0; 91 bits2read<=0; 92 vcttemp<=0; 93 end 94 else 95 begin 96 transpzn[7:0] = bitbuffer[8:1]^bitbuffer[7:0];//判断采样到的bit发生变化的位置 97 bits2read[7:0] <=bitbuffer[7:0];//再次缓存bitbuffer,供下个时钟判决采样值 98 99 100 /* 101 下面采用阻塞赋值 使得transvct向量组可以循环移动 102 若transpzn当前bit为1 则向量初始为1000b 否则向右循环移动 在0100处采样 得到vcttemp作为最终采样位置去采bits2read的值 103 */ 104 if(transpzn[7] || transvct[0][0]) //此位是跳变沿或者上一次向量为0001 初始化为1000 105 transvct[7][3:0] = 4'b1000; 106 else 107 transvct[7][3:0] = transvct[0][3:0]>>1; //将上一个位置的向量右移至本位 108 109 if(transpzn[6] || transvct[7][0]) //此位是跳变沿或者上一次向量为0001 初始化为1000 110 transvct[6][3:0] = 4'b1000; 111 else 112 transvct[6][3:0] = transvct[7][3:0]>>1; //将上一个位置的向量右移至本位 113 114 if(transpzn[5] || transvct[6][0]) //此位是跳变沿或者上一次向量为1000 初始化为1000 115 transvct[5][3:0] = 4'b1000; 116 else 117 transvct[5][3:0] = transvct[6][3:0]>>1; //将上一个位置的向量左移至本位 118 119 if(transpzn[4] || transvct[5][0]) //此位是跳变沿或者上一次向量为0001 初始化为1000 120 transvct[4][3:0] = 4'b1000; 121 else 122 transvct[4][3:0] = transvct[5][3:0]>>1; //将上一个位置的向量右移至本位 123 124 if(transpzn[3] || transvct[4][0]) //此位是跳变沿或者上一次向量为0001 初始化为1000 125 transvct[3][3:0] = 4'b1000; 126 else 127 transvct[3][3:0] = transvct[4][3:0]>>1; //将上一个位置的向量右移至本位 128 129 if(transpzn[2] || transvct[3][0]) //此位是跳变沿或者上一次向量为0001 初始化为1000 130 transvct[2][3:0] = 4'b1000; 131 else 132 transvct[2][3:0] = transvct[3][3:0]>>1; //将上一个位置的向量右移至本位 133 134 if(transpzn[1] || transvct[2][0]) //此位是跳变沿或者上一次向量为0001 初始化为1000 135 transvct[1][3:0] = 4'b1000; 136 else 137 transvct[1][3:0] = transvct[2][3:0]>>1; //将上一个位置的向量右移至本位 138 139 if(transpzn[0] || transvct[1][0]) //此位是跳变沿或者上一次向量为0001 初始化为1000 140 transvct[0][3:0] = 4'b1000; 141 else 142 transvct[0][3:0] = transvct[1][3:0]>>1; //将上一个位置的向量右移至本位 143 144 145 /* 146 在向量0100b处作为采样位置,下一时钟在vcttemp为1的bit位采样bits2read中的值输出 147 */ 148 vcttemp <= {transvct[7][2],transvct[6][2],transvct[5][2],transvct[4][2],transvct[3][2],transvct[2][2],transvct[1][2],transvct[0][2]}; 149 150 end 151 end 152 153 always @ (posedge clk0) 154 begin 155 if(!nRst) 156 begin 157 judgestate=0; 158 samplebyte=0; 159 bytebuffer=0; 160 ByteOut<=0; 161 ByteWR<=0; 162 bitcount=4'd7; 163 zerocount=0; 164 beginen<=0; 165 end 166 else 167 begin 168 /* 169 连续8bit为10101010时 judgestate=8 传输有效 后面的8个bit循环构成字节 当连续出现10个0 表示传输结束 170 */ 171 for(vctcount=8;vctcount>=1;vctcount=vctcount-1) 172 begin 173 if(vcttemp[vctcount-1]) 174 begin 175 case(judgestate) 176 4'd0: 177 begin 178 if(bits2read[vctcount-1]) //1 179 begin 180 judgestate = 4'd1; 181 end 182 else 183 judgestate = 0; 184 end 185 4'd1: 186 begin 187 if(!bits2read[vctcount-1]) //0 188 begin 189 judgestate = 4'd2; 190 end 191 else //若为1 重新检查下一个是否为0 192 judgestate = 1; 193 end 194 4'd2: 195 begin 196 if(bits2read[vctcount-1]) //1 197 begin 198 judgestate = 4'd3; 199 end 200 else 201 judgestate = 0; 202 end 203 4'd3: 204 begin 205 if(!bits2read[vctcount-1]) //0 206 begin 207 judgestate = 4'd4; 208 end 209 else//若为1 重新检查下一个是否为0 210 judgestate = 1; 211 end 212 4'd4: 213 begin 214 if(bits2read[vctcount-1]) //1 215 begin 216 judgestate = 4'd5; 217 end 218 else 219 judgestate = 0; 220 end 221 4'd5: 222 begin 223 if(!bits2read[vctcount-1]) //0 224 begin 225 judgestate = 4'd6; 226 end 227 else//若为1 重新检查下一个是否为0 228 judgestate = 1; 229 end 230 4'd6: 231 begin 232 if(bits2read[vctcount-1]) //1 233 begin 234 judgestate = 4'd7; 235 end 236 else 237 judgestate = 0; 238 end 239 4'd7: 240 begin 241 if(!bits2read[vctcount-1])//0 242 begin 243 judgestate = 4'd8; 244 bitcount=4'd7; // 传输开始 准备将第一个bit存入输出MSB 245 end 246 else//若为1 重新检查下一个是否为0 247 judgestate = 1; 248 end 249 4'd8: 250 begin 251 if( bits2read[vctcount-1] && (zerocount>=4'd10) ) //若某个为1的bit前面有连续10个0 表示是扰码 忽略掉 并重新开始对0计数 252 zerocount=0; 253 else if( !bits2read[vctcount-1] && (onecount>=4'd10) ) //若某个为0的bit前面有连续10个1 表示是扰码 忽略掉 并重新开始对0计数 254 onecount=0; 255 else 256 begin 257 samplebyte[bitcount] = bits2read[vctcount-1];//将串行bit放入samplebyte中 258 if(bitcount==0) // 若计数器归零 将samplebyte暂存于bytebuffer中 259 begin 260 bitcount=7; 261 ByteOut<=samplebyte; 262 ByteWR<=0; 263 end 264 else 265 bitcount=bitcount-1; 266 267 268 if(bitcount==4) //ByteWR产生跳变 269 begin 270 if(!beginen)//将传输开始后第一个无效字节屏蔽 271 beginen<=1; 272 else 273 ByteWR<= 1; 274 end 275 276 if(!bits2read[vctcount-1]) //若出现0 统计连续0的个数 达到14个 表示传输结束 重新回到0状态 等待10101010的出现 277 zerocount=zerocount+1; 278 else 279 zerocount=0; 280 281 if(bits2read[vctcount-1]) //若出现1 统计连续1的个数 282 onecount=onecount+1; 283 else 284 onecount=0; 285 286 if(zerocount>=5'd14) //连续出现的0达到14个 结束 287 begin 288 judgestate=0; 289 samplebyte=0; 290 bytebuffer=0; 291 ByteOut<=0; 292 ByteWR<=0; 293 bitcount=7; 294 zerocount=0; 295 beginen<=0; 296 end 297 else 298 judgestate=8; 299 300 end 301 end 302 endcase 303 end 304 end 305 end 306 end 307 endmodule
posted on 2025-01-09 10:12 taylorrrrrrrrrr 阅读(4) 评论(0) 编辑 收藏 举报