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

📄 par_framer.v

📁 使用IDELAY实现8倍过采样异步串行信号恢复信号
💻 V
📖 第 1 页 / 共 2 页
字号:
        trs_match2_l1[ 9] <= ~|in_vector[22:19];
        trs_match2_l1[10] <= ~|in_vector[23:20];
        trs_match2_l1[11] <= ~|in_vector[24:21];
        trs_match2_l1[12] <= ~|in_vector[25:22];
        trs_match2_l1[13] <= ~|in_vector[26:23];
        trs_match2_l1[14] <= ~|in_vector[27:24];
        trs_match2_l1[15] <= ~|in_vector[28:25];

        trs_match3_l1[ 0] <= ~|in_vector[23:20];
        trs_match3_l1[ 1] <= ~|in_vector[24:21];
        trs_match3_l1[ 2] <= ~|in_vector[25:22];
        trs_match3_l1[ 3] <= ~|in_vector[26:23];
        trs_match3_l1[ 4] <= ~|in_vector[27:24];
        trs_match3_l1[ 5] <= ~|in_vector[28:25];
        trs_match3_l1[ 6] <= ~|in_vector[29:26];
        trs_match3_l1[ 7] <= ~|in_vector[30:27];
        trs_match3_l1[ 8] <= ~|in_vector[31:28];
        trs_match3_l1[ 9] <= ~|in_vector[32:29];
        trs_match3_l1[10] <= ~|in_vector[33:30];
        trs_match3_l1[11] <= ~|in_vector[34:31];
        trs_match3_l1[12] <= ~|in_vector[35:32];
        trs_match3_l1[13] <= ~|in_vector[36:33];
        trs_match3_l1[14] <= ~|in_vector[37:34];
        trs_match3_l1[15] <= ~|in_vector[38:35];
    end

// second level of gates

always @ (trs_match1_l1)
    begin
        trs_match1[0] <= trs_match1_l1[ 0] & trs_match1_l1[ 4] & trs_match1_l1[ 6];
        trs_match1[1] <= trs_match1_l1[ 1] & trs_match1_l1[ 5] & trs_match1_l1[ 7];
        trs_match1[2] <= trs_match1_l1[ 2] & trs_match1_l1[ 6] & trs_match1_l1[ 8];
        trs_match1[3] <= trs_match1_l1[ 3] & trs_match1_l1[ 7] & trs_match1_l1[ 9];
        trs_match1[4] <= trs_match1_l1[ 4] & trs_match1_l1[ 8] & trs_match1_l1[10];
        trs_match1[5] <= trs_match1_l1[ 5] & trs_match1_l1[ 9] & trs_match1_l1[11];
        trs_match1[6] <= trs_match1_l1[ 6] & trs_match1_l1[10] & trs_match1_l1[12];
        trs_match1[7] <= trs_match1_l1[ 7] & trs_match1_l1[11] & trs_match1_l1[13];
        trs_match1[8] <= trs_match1_l1[ 8] & trs_match1_l1[12] & trs_match1_l1[14];
        trs_match1[9] <= trs_match1_l1[ 9] & trs_match1_l1[13] & trs_match1_l1[15];
    end

always @ (trs_match2_l1)
    begin
        trs_match2[0] <= trs_match2_l1[ 0] & trs_match2_l1[ 4] & trs_match2_l1[ 6];
        trs_match2[1] <= trs_match2_l1[ 1] & trs_match2_l1[ 5] & trs_match2_l1[ 7];
        trs_match2[2] <= trs_match2_l1[ 2] & trs_match2_l1[ 6] & trs_match2_l1[ 8];
        trs_match2[3] <= trs_match2_l1[ 3] & trs_match2_l1[ 7] & trs_match2_l1[ 9];
        trs_match2[4] <= trs_match2_l1[ 4] & trs_match2_l1[ 8] & trs_match2_l1[10];
        trs_match2[5] <= trs_match2_l1[ 5] & trs_match2_l1[ 9] & trs_match2_l1[11];
        trs_match2[6] <= trs_match2_l1[ 6] & trs_match2_l1[10] & trs_match2_l1[12];
        trs_match2[7] <= trs_match2_l1[ 7] & trs_match2_l1[11] & trs_match2_l1[13];
        trs_match2[8] <= trs_match2_l1[ 8] & trs_match2_l1[12] & trs_match2_l1[14];
        trs_match2[9] <= trs_match2_l1[ 9] & trs_match2_l1[13] & trs_match2_l1[15];
    end

always @ (trs_match3_l1)
    begin
        trs_match3[0] <= trs_match3_l1[ 0] & trs_match3_l1[ 4] & trs_match3_l1[ 6];
        trs_match3[1] <= trs_match3_l1[ 1] & trs_match3_l1[ 5] & trs_match3_l1[ 7];
        trs_match3[2] <= trs_match3_l1[ 2] & trs_match3_l1[ 6] & trs_match3_l1[ 8];
        trs_match3[3] <= trs_match3_l1[ 3] & trs_match3_l1[ 7] & trs_match3_l1[ 9];
        trs_match3[4] <= trs_match3_l1[ 4] & trs_match3_l1[ 8] & trs_match3_l1[10];
        trs_match3[5] <= trs_match3_l1[ 5] & trs_match3_l1[ 9] & trs_match3_l1[11];
        trs_match3[6] <= trs_match3_l1[ 6] & trs_match3_l1[10] & trs_match3_l1[12];
        trs_match3[7] <= trs_match3_l1[ 7] & trs_match3_l1[11] & trs_match3_l1[13];
        trs_match3[8] <= trs_match3_l1[ 8] & trs_match3_l1[12] & trs_match3_l1[14];
        trs_match3[9] <= trs_match3_l1[ 9] & trs_match3_l1[13] & trs_match3_l1[15];
    end

//
// third level of gates generates a unary bit pattern indicating which offsets
// contain valid TRS symbols
//
assign trs_match_all = trs_match1 & trs_match2 & trs_match3;

//
// If any of the bits in trs_match_all are asserted, the assert trs_detected        
//
assign trs_detected = |trs_match_all;

//
// The following asserts trs_error if more than one bit is set in trs_match_all
//
always @ (trs_match_all)
    case (trs_match_all)
        10'b00_0000_0000: trs_error  <= 0;
        10'b00_0000_0001: trs_error  <= 0;
        10'b00_0000_0010: trs_error  <= 0;
        10'b00_0000_0100: trs_error  <= 0;
        10'b00_0000_1000: trs_error  <= 0;
        10'b00_0001_0000: trs_error  <= 0;
        10'b00_0010_0000: trs_error  <= 0;
        10'b00_0100_0000: trs_error  <= 0;
        10'b00_1000_0000: trs_error  <= 0;
        10'b01_0000_0000: trs_error  <= 0;
        10'b10_0000_0000: trs_error  <= 0;
        default:          trs_error  <= 1;
    endcase

//
// The following assignments encode the trs_match_all vector into a binary
// offset code.
//
assign offset_val[0] = trs_match_all[1] | trs_match_all[3] | trs_match_all[5] |
                       trs_match_all[7] | trs_match_all[9];
assign offset_val[1] = trs_match_all[2] | trs_match_all[3] | trs_match_all[6] |
                       trs_match_all[7];
assign offset_val[2] = trs_match_all[4] | trs_match_all[5] | trs_match_all[6] |
                       trs_match_all[7];
assign offset_val[3] = trs_match_all[8] | trs_match_all[9];


//
// offset_reg: barrel shifter offset register
//
// The offset_reg loads the offset_val whenever trs_detected is
// asserted and trs_error is not asserted and frame_en is asserted.
//
always @ (posedge clk or posedge rst)
    if (rst)
        offset_reg <= 0;
    else if (ce) 
        if (trs_detected & ~trs_error & frame_en)
            offset_reg <= offset_val;

//
// New start position detector
// 
// A comparison between offset_val and offset_reg determines if
// the new offset is different than the current one. If there is
// a mismatch and frame_en is not asserted, then the nsp output
// will be asserted.
//
assign new_offset = offset_val != offset_reg;

always @ (posedge clk or posedge rst)
    if (rst)
        nsp <= 1;
    else if (ce)        
        if (trs_detected & ~trs_error)
            nsp <= ~frame_en & new_offset;

//
// barrel_in: barrel shifter input register
//
// This register implements a pipeline delay stage so that the
// barrel shifter's data input matches the delay on the offset
// input caused by the offset_reg.
//
always @ (posedge clk or posedge rst)
    if (rst)
        barrel_in <= 0;
    else if (ce)
        barrel_in <= {in2_reg[8:0], in3_reg};

//
// barrel shifter
//
// The barrel shifter extracts a 10-bit field from the 19-bit barrel_in vector.
// The bits extracted depend on the value of the offset_reg. If offset_reg is
// zero, barrel_in[9:0] are output by the barrel shifter. At the other extreme,
// an offset_reg value of 9 causes the barrel shifter to output barrel_in[18:9].
//
// The barrel shifter can be described in many ways. One way is a simple
// shift assignment as shown below:
//
// assign barrel_out = barrel_in >> offset_reg;
//
// This produces excellent results with FPGA Express, but doesn't produce such
// good results with the current version of XST.
//
// Another method is to explicitly code the barrel shifter as two levels of
// MUXes. The first level consists of thirteen 3-input MUXes which provide
// the course shifting in increments of four bits. The second level consists of
// ten 4-input MUXes which provide fine shifting (1-bit increments). This method
// produces a much better result with XST, but produces a very small (4 LUTs)
// larger implementation with FPGA Express.
//
assign bs_in = {2'b00, barrel_in};
assign bs_sm = offset_reg[3:2];
assign bs_sl = offset_reg[1:0];

always @ (bs_in or bs_sm)
    for (i = 0; i < 13; i = i + 1)
        case (bs_sm)
            2'b00: bs_m1[i] <= bs_in[i];
            2'b01: bs_m1[i] <= bs_in[i + 4];
            2'b10: bs_m1[i] <= bs_in[i + 8]; 
            2'b11: bs_m1[i] <= 1'b0;
        endcase

always @ (bs_m1 or bs_sl)
    for (j = 0; j < 10; j = j + 1)
        case (bs_sl)
            2'b00: barrel_out[j] <= bs_m1[j];
            2'b01: barrel_out[j] <= bs_m1[j + 1];
            2'b10: barrel_out[j] <= bs_m1[j + 2];
            2'b11: barrel_out[j] <= bs_m1[j + 3];
        endcase

//
// The output of the module is the barrel shifter output
//
assign q = barrel_out;

//
// 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]};

assign trs = |trs_out;

endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -