case语句写法 理解
//为了完成 RGB 图像数据 8b 转 10b 的编码
//此为xilinx 官方提供的编码模块代码
// TMDS 通过逻辑算法将 8 位字符数据通过编码转换为 10 位字符数据,前 8 位数据由原始信号经运算后
// 获得,第 9 位表示运算的方式,1 表示异或 0 表示异或非。经过 DC 平衡后(第 10 位),采用差分信号传输
// 数据。第 10 位实际是一个反转标志位,1 表示进行了反转而 0 表示没有反转,从而达到 DC 平衡。
// D D:输入视频像素信号
// C1 C0 C1,C0:控制信号
// DE DE:使能信号
// Cnt Cnt寄存上次编码过程中0的个数减1的个数
// N1{X} 输入视频像素信号中1的个数
// N0{X} 输入视频像素信号中0的个数
// q_out 编码输出信号
// 首先要判断输入的像素数据1的个数是否大于4或者输入像素等于4且最低位为0,即(N1{D}>4)|| (N1{D}==4 && D[0]==0)为真,
// 则执行右边的运算,如果上述条件为假,则执行左边的运算。q_m只是一个临时寄存器,用来寄存中间数据。
// 右边的运算是对输入的像素数据进行同或运算(将输入数据最低位寄存在q_m最低位,
// 然后q_m的低位与输入数据的下一位数据同或得到q_m当前位数据),并且第9比特q_m[8]赋值为0,左边的运算是对输入的像素数据进行异或运算,
// 并且第9比特q_m[8]赋值为1。第9位就是用来表示TMDS对输入数据采用异或还是同或运算的
`timescale 1 ps / 1ps
module dvi_encoder (
input clkin, //
input rstin, //
input [7:0] din, //
input c0, // 行同步信号
input c1, // 场同步信号
input de, // 使能
output reg [9:0] dout //
);
reg [3:0] n1d; //number of 1s in din
reg [7:0] din_q;
//计算像素数据中“1”的个数
always @ (posedge clkin) begin
n1d <=#1 din[0] + din[1] + din[2] + din[3] + din[4] + din[5] +
din[6] + din[7];
din_q <=#1 din;
end
wire decision1; //1或者0
assign decision1 = (n1d > 4'h4) | ((n1d == 4'h4) & (din_q[0] ==
1'b0));
wire [8:0] q_m;///先转换为9位
assign q_m[0] = din_q[0];
assign q_m[1] = (decision1) ? (q_m[0] ^~ din_q[1]) : (q_m[0] ^
din_q[1]);
assign q_m[2] = (decision1) ? (q_m[1] ^~ din_q[2]) : (q_m[1] ^
din_q[2]);
assign q_m[3] = (decision1) ? (q_m[2] ^~ din_q[3]) : (q_m[2] ^
din_q[3]);
assign q_m[4] = (decision1) ? (q_m[3] ^~ din_q[4]) : (q_m[3] ^
din_q[4]);
assign q_m[5] = (decision1) ? (q_m[4] ^~ din_q[5]) : (q_m[4] ^
din_q[5]);
assign q_m[6] = (decision1) ? (q_m[5] ^~ din_q[6]) : (q_m[5] ^
din_q[6]);
assign q_m[7] = (decision1) ? (q_m[6] ^~ din_q[7]) : (q_m[6] ^
din_q[7]);
assign q_m[8] = (decision1) ? 1'b0 : 1'b1;
reg [3:0] n1q_m, n0q_m;
always @ (posedge clkin) begin
n1q_m <=#1 q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] +
q_m[6] + q_m[7]; //低八位的q_m中1的数量
n0q_m <=#1 4'h8 - (q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] +
q_m[5] + q_m[6] + q_m[7]); //低八位的q_m中0的数量
end
parameter CTRLTOKEN0 = 10'b1101010100;
parameter CTRLTOKEN1 = 10'b0010101011;
parameter CTRLTOKEN2 = 10'b0101010100;
parameter CTRLTOKEN3 = 10'b1010101011;
reg [4:0] cnt;
wire decision2, decision3;
assign decision2 = (cnt == 5'h0) | (n1q_m == n0q_m);
assign decision3 = (~cnt[4] & (n1q_m > n0q_m)) | (cnt[4] & (n0q_m >
n1q_m));
reg de_q, de_reg;
reg c0_q, c1_q;
reg c0_reg, c1_reg;
reg [8:0] q_m_reg;
always @ (posedge clkin) begin //使能 场同步 行同步 q_m缓存
de_q <=#1 de;
de_reg <=#1 de_q;
c0_q <=#1 c0;
c0_reg <=#1 c0_q;
c1_q <=#1 c1;
c1_reg <=#1 c1_q;
q_m_reg <=#1 q_m;
end
always @ (posedge clkin or posedge rstin) begin
if(rstin) begin
dout <= 10'h0;
cnt <= 5'h0;
end else begin
if (de_reg) begin //de使能
if(decision2) begin
dout[9] <=#1 ~q_m_reg[8];
dout[8] <=#1 q_m_reg[8];
dout[7:0] <=#1 (q_m_reg[8]) ? q_m_reg[7:0] : ~q_m_reg[7:0];
cnt <=#1 (~q_m_reg[8]) ? (cnt + n0q_m - n1q_m) : (cnt +
n1q_m - n0q_m);
end else begin
if(decision3) begin
dout[9] <=#1 1'b1;
dout[8] <=#1 q_m_reg[8];
dout[7:0] <=#1 ~q_m_reg[7:0];
cnt <=#1 cnt + {q_m_reg[8], 1'b0} + (n0q_m - n1q_m);
end else begin
dout[9] <=#1 1'b0;
dout[8] <=#1 q_m_reg[8];
dout[7:0] <=#1 q_m_reg[7:0];
cnt <=#1 cnt - {~q_m_reg[8], 1'b0} + (n1q_m - n0q_m);
end
end
end else begin//de不使能
case ({c1_reg, c0_reg})
2'b00: dout <=#1 CTRLTOKEN0;
2'b01: dout <=#1 CTRLTOKEN1;
2'b10: dout <=#1 CTRLTOKEN2;
default: dout <=#1 CTRLTOKEN3;
endcase
cnt <=#1 5'h0;
end
end
end
endmodule