📄 hdsdi_framer_mult.v
字号:
nsp <= 1;
else if (ce)
if (trs_detected)
nsp <= ~frame_en & new_offset;
//
// barrel shifter input register
//
always @ (posedge clk or posedge rst)
if (rst)
barrel_in <= 0;
else if (ce)
barrel_in <= {dly_reg[18:0], dly_reg2};
//
// Barrel shifter
//
// The barrel shifter extracts a 20-bit field from the bs_in vector.
// The bits extracted depend on the value of the offset_reg. The barrel shifter
// shifts the 39-bit input vector left by 0 to 19 bit positions. If the shift
// code is zero, then the resulting output is barrel_in[19:0]. On the other
// extreme, if the shift code is 19, then the resulting output is
// barrel_in[38:19].
//
// This version of the barrel shifter is implemented in two levels. The top
// level shifts the input vector either 0 or 12 bit positions right. The bottom
// level shifts zero to 11 bit positions right. MULT18X18 blocks are used to
// implement both levels.
//
//
// Barrel shifter top level
//
// This level of the barrel shifter will right shift the input vector either 0
// bit positions or 12 bit positions, depending on the sc_top bit.
//
// Three 18X18 multipliers are used at the top level to implement 2:1 MUXes.
// Each 18x18 multiplier can be used for 9 2:1 MUXes. A for loop creates an
// input vector for the top level MUXes. Another for loop picks all the odd
// outputs from the three MUXes for the 27-bit wide output vector to feed to
// the next level of the barrel shifter.
//
// The inputs to the A term of the multipliers are arranged like this:
//
// BS_TOP_A: 8 20 7 19 6 18 5 17 4 16 3 15 2 14 1 13 0 12
// BS_TOP_B: 17 29 16 28 15 27 14 26 13 25 12 24 11 23 10 22 9 21
// BS_TOP_C: 26 38 25 37 24 36 23 35 22 34 21 33 20 32 19 31 18 30
//
// If the sc_top shift code bit is zero, the a multiplier value of 1 is input
// to the B term of each multiplier. This results in each input bit going
// straight out to the corresponding output bit (i.e. bit 1 of the A input
// appears on bit 1 of the P port.
//
always @ (barrel_in)
for (i = 0; i < 27; i = i + 1)
begin
bs_in[i*2] <= barrel_in[i+12];
bs_in[i*2+1] <= barrel_in[i];
end
MULT18X18 BS_TOP_A (
.A (bs_in[17:0]),
.B ({16'b0, sc_top, ~sc_top}),
.P (bstop_a)
);
MULT18X18 BS_TOP_B (
.A (bs_in[35:18]),
.B ({16'b0, sc_top, ~sc_top}),
.P (bstop_b)
);
MULT18X18 BS_TOP_C (
.A (bs_in[53:36]),
.B ({16'b0, sc_top, ~sc_top}),
.P (bstop_c)
);
always @ (bstop_a or bstop_b or bstop_c)
for (j = 0; j < 9; j = j + 1)
begin
bstop[j] <= bstop_a[j * 2 + 1];
bstop[j + 9] <= bstop_b[j * 2 + 1];
bstop[j + 18] <= bstop_c[j * 2 + 1];
end
//
// Bottom level of barrel shifter
//
// This level of the barrel shifter will shift the output of the top level left
// 0 to 11 bits. Note, however, that it only needs to shift the vector 7 bits
// to the left if the top level is doing a 12-bit left shift.
//
// The bottom level of the barrel shifter is made of another three 18x18
// multipliers. In this level, each multiplier implements seven 12:1 MUXes.
// The inputs to A input of the multipliers are connected like this:
//
// BS_BOT_A: bstop[17:0]
// BS_BOT_B: bstop[24:7]
// BS_BOT_C: {barrel_in[31:27], bstop[26:14]}
//
// BS_BOT_C has its MS 5 bits connected directly to the MS 5 bits from the
// barrel shifter's input vector rather than from the 2:1 MUXes of the top
// level. This is because these bits positions are only used when shifting
// left more than 7 bits which can only occur if the top level is not shifting.
//
//
MULT18X18 BS_BOT_A (
.A (bstop[17:0]),
.B ({6'b0, sc_bot}),
.P (bsbot_a)
);
MULT18X18 BS_BOT_B (
.A (bstop[24:7]),
.B ({6'b0, sc_bot}),
.P (bsbot_b)
);
MULT18X18 BS_BOT_C (
.A ({barrel_in[31:27], bstop[26:14]}),
.B ({6'b0, sc_bot}),
.P (bsbot_c)
);
assign barrel_out = {bsbot_c[16:11], bsbot_b[17:11], bsbot_a[17:11]};
//
// Barrel shifter shift code generation
//
// This logic takes the offset_reg value and produces shift codes for the top
// and bottom level MUXes of the barrel shifter. sc_bot is 12-bit vector that
// always has only one bit asserted. The value is dependent upon offset_reg MOD
// 12, such that if this result is 0, then sc_bot = 2048. If the result is 1,
// sc_bot = 1024. And so on, until the result is 11 and the shift code is 1.
// sc_top is 0 for offset_reg values of 11 or less and 1 otherwise.
//
always @ (offset_reg)
case(offset_reg)
5'b00000: begin
sc_top <= 1'b0;
sc_bot <= 12'b1000_0000_0000;
end
5'b00001: begin
sc_top <= 1'b0;
sc_bot <= 12'b0100_0000_0000;
end
5'b00010: begin
sc_top <= 1'b0;
sc_bot <= 12'b0010_0000_0000;
end
5'b00011: begin
sc_top <= 1'b0;
sc_bot <= 12'b0001_0000_0000;
end
5'b00100: begin
sc_top <= 1'b0;
sc_bot <= 12'b0000_1000_0000;
end
5'b00101: begin
sc_top <= 1'b0;
sc_bot <= 12'b0000_0100_0000;
end
5'b00110: begin
sc_top <= 1'b0;
sc_bot <= 12'b0000_0010_0000;
end
5'b00111: begin
sc_top <= 1'b0;
sc_bot <= 12'b0000_0001_0000;
end
5'b01000: begin
sc_top <= 1'b0;
sc_bot <= 12'b0000_0000_1000;
end
5'b01001: begin
sc_top <= 1'b0;
sc_bot <= 12'b0000_0000_0100;
end
5'b01010: begin
sc_top <= 1'b0;
sc_bot <= 12'b0000_0000_0010;
end
5'b01011: begin
sc_top <= 1'b0;
sc_bot <= 12'b0000_0000_0001;
end
5'b01100: begin
sc_top <= 1'b1;
sc_bot <= 12'b1000_0000_0000;
end
5'b01101: begin
sc_top <= 1'b1;
sc_bot <= 12'b0100_0000_0000;
end
5'b01110: begin
sc_top <= 1'b1;
sc_bot <= 12'b0010_0000_0000;
end
5'b01111: begin
sc_top <= 1'b1;
sc_bot <= 12'b0001_0000_0000;
end
5'b10000: begin
sc_top <= 1'b1;
sc_bot <= 12'b0000_1000_0000;
end
5'b10001: begin
sc_top <= 1'b1;
sc_bot <= 12'b0000_0100_0000;
end
5'b10010: begin
sc_top <= 1'b1;
sc_bot <= 12'b0000_0010_0000;
end
5'b10011: begin
sc_top <= 1'b1;
sc_bot <= 12'b0000_0001_0000;
end
default: begin
sc_top <= 1'b0;
sc_bot <= 12'b1000_0000_0000;
end
endcase
//
// Output registers
//
always @ (posedge clk or posedge rst)
if (rst)
begin
c_int <= 0;
y_int <= 0;
end
else if (ce)
begin
c_int <= barrel_out[9:0];
y_int <= barrel_out[19:10];
end
assign c = c_int;
assign y = y_int;
//
// trs: trs output generation logic
//
// The trs_out register is a 4-bit shift register which shifts everytime
// the bit_cntr[0] bit is asserted. The trs output signal is the OR of
// the four bits in this register so it becomes asserted when the first
// character of the TRS symbol is output and remains asserted for the
// following three characters of the TRS symbol.
//
always @ (posedge clk or posedge rst)
if (rst)
trs_out <= 0;
else if (ce)
trs_out <= {trs_detected, trs_out[3:1]};
always @ (posedge clk or posedge rst)
if (rst)
trs <= 0;
else if (ce)
trs <= |trs_out;
always @ (posedge clk or posedge rst)
if (rst)
xyz_int <= 1'b0;
else if (ce)
xyz_int <= trs_out[0];
assign xyz = xyz_int;
assign eav = xyz_int & y_int[6];
assign sav = xyz_int & ~y_int[6];
//
// TRS error detector
//
// This code examines the protection bits in the XYZ word and asserts the
// trs_err output if an error is detected.
//
assign trs_err = xyz_int & (
(y_int[5] ^ y_int[6] ^ y_int[7]) |
(y_int[4] ^ y_int[8] ^ y_int[6]) |
(y_int[3] ^ y_int[8] ^ y_int[7]) |
(y_int[2] ^ y_int[8] ^ y_int[7] ^ y_int[6]) |
~y_int[9] | y_int[1] | y_int[0]);
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -