⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hdsdi_framer_mult.v

📁 SDI接口的源程序,包括扰码编码,并串转换,用VHDL硬件描述语言编写
💻 V
📖 第 1 页 / 共 2 页
字号:
        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 + -