// // // DCS Decoder Block Version 2.00 for FPGA/ASIC targets // Adrian Tang 2016 // // You need to clock at twice the spreading-chip rate (IE 7.5 MS/s) // Verilog 2001 // // Typically a good PN code will be same number of 1s and 0s for minimal DC // // Usage // // 1. Reset the block. // 2. As PN_codes are recgonized the bits they represent will be added to the output buffer // 3. number_of_bits holds the current index of the output buffer // bits from output_buffer[0] to output_buffer[number_of_bits-1] are valid // 4. They will be streamed out the USART module DCS_decoder(reset, clk, track_stream,data_detect,start_readout,send_done,TXD, baud_clock); //MTH code flipped for reference: 1011101000001001100011110010101 //MTH code inverte for reference: 0100010111110110011100001101010 //Parameters that control the block behavior parameter PN_code = 31'b1010100111100011001000001011101; //MTH Secret Spread Code parameter confidence_threshold = 7'd26; //Correlator Confidence threshold //Main Block Control input clk; //mater clock on the block (7.5 MS/s) input reset; //master reset for the block tripped after each packet input start_readout; //trigger for reading out the data reg sequencer; //Block Inputs input track_stream; //dsss stream from track //Captured Data reg [9:0] number_of_bits; //Counts the number of bits detected (supports upt o a 255 bit code) reg [1023:0] output_buffer; //Buffer storing the captured bits //Internal registers reg [61:0] sr_reg; //Input shift register packet streams into reg [30:0] eve_reg; //Even phase subregister for decoder reg [30:0] odd_reg; //Odd phase subregister for decoder //intermediate correlation values reg [30:0] CE; //even phase correlation reg [30:0] CO; //odd phase correlation reg [7:0] CE_TOTAL; //Accumulated even confidence reg [7:0] CO_TOTAL; //Accumulated even confidence //Confidence Intervals for dsss wire [7:0] con_high; wire [7:0] con_low; //---------------Generate the tow level confidence levels------------------------------ assign con_high = confidence_threshold; //we need more than (confidence_threshold) out of 31 spread chips to match to take it as 1 assign con_low = 7'd31 - confidence_threshold; //we need more than (confidence_threshold) out of 31 spread chips NOT to match to take it as 0 //---------------------------readout related------------------------------------------------ output data_detect; //Indicates if data was detected by the system reg data_detect; reg readout_mode; //Puts the system into readout mode output send_done; //Indicates if a UART packet was sent wire send_done; output TXD; //Actual UART data stream wire TXD; output baud_clock; //Lets us monitor the clock for the serial port wire baud_clock; reg transmitnow; //register to fire the transmitter reg [7:0] tx_byte; //Byte to be transmitted by UART reg [9:0] result_counter; //counts which capture bit is currently being output reg [18:0] readout_clk; //readout clock divider counts to 524287 //---------------------------readout related------------------------------------------------ //instance of the UART block UART UART1(transmitnow, clk, TXD, tx_byte, send_done, baud_clock); //----decoder core operation begins here always@ (posedge clk) begin //always on clock synchronous ooperation //------------------------------------------------------------------------------------------------------------------------------------------------------------------------ // MAIN CORRELATOR //------------------------------------------------------------------------------------------------------------------------------------------------------------------------ //input 62 bit shift register to take in the track data sr_reg <= sr_reg >> 1; sr_reg[61] <= track_stream; //-----------------Assign the odd and even registers from the main shift register in order to cover both possible phases---------------- odd_reg <= {sr_reg[60],sr_reg[58],sr_reg[56],sr_reg[54],sr_reg[52],sr_reg[50], sr_reg[48],sr_reg[46],sr_reg[44],sr_reg[42],sr_reg[40],sr_reg[38], sr_reg[36],sr_reg[34],sr_reg[32],sr_reg[30],sr_reg[28],sr_reg[26], sr_reg[24],sr_reg[22],sr_reg[20],sr_reg[18],sr_reg[16],sr_reg[14], sr_reg[12],sr_reg[10],sr_reg[8], sr_reg[6], sr_reg[4], sr_reg[2], sr_reg[0]}; eve_reg <= {sr_reg[61],sr_reg[59],sr_reg[57],sr_reg[55],sr_reg[53],sr_reg[51], sr_reg[49],sr_reg[47],sr_reg[45],sr_reg[43],sr_reg[41],sr_reg[39], sr_reg[37],sr_reg[35],sr_reg[33],sr_reg[31],sr_reg[29],sr_reg[27], sr_reg[25],sr_reg[23],sr_reg[21],sr_reg[19],sr_reg[17],sr_reg[15], sr_reg[13],sr_reg[11],sr_reg[9], sr_reg[7], sr_reg[5], sr_reg[3], sr_reg[1]}; //-------------Generate the 4 correlation terms-------------- //Even Phase Positive CE <= eve_reg ~^ PN_code; //Odd Phase Positive CO <= odd_reg ~^ PN_code; //-------------Compute the total correlation-------------- CE_TOTAL = CE[30] + CE[29] + CE[28] + CE[27] + CE[26] + CE[25] + CE[24] + CE[23] + CE[22] + CE[21] + CE[20] + CE[19] + CE[18] + CE[17] + CE[16] + CE[15] + CE[14] + CE[13] + CE[12] + CE[11] + CE[10] + CE[9] + CE[8] + CE[7] + CE[6] + CE[5] + CE[4] + CE[3] + CE[2] + CE[1] + CE[0]; CO_TOTAL = CO[30] + CO[29] + CO[28] + CO[27] + CO[26] + CO[25] + CO[24] + CO[23] + CO[22] + CO[21] + CO[20] + CO[19] + CO[18] + CO[17] + CO[16] + CO[15] + CO[14] + CO[13] + CO[12] + CO[11] + CO[10] + CO[9] + CO[8] + CO[7] + CO[6] + CO[5] + CO[4] + CO[3] + CO[2] + CO[1] + CO[0]; if(reset==0) begin //if the block is in reset mode number_of_bits<=10'd0; //reset the bit counter output_buffer<=1024'd0; //Clear the output buffer sequencer<=1'b0; data_detect<=1'b0; readout_mode <=1'b0; transmitnow <=1'b0; tx_byte<=8'd0; result_counter<=10'd0; readout_clk<=19'd0; end else begin if(readout_mode==1'b0) begin//if the block is running sequencer <= ~sequencer; //This ones a bit complicated. Ideally we have two samples per spreading chip but we don't want to double count if(sequencer==1) //as the chip moves from the even side to the odd side, so we only look at both even and odd every 2 clocks to prevent double counting the same PN_code begin //-------------Decode to the output packet buffer-------------- if (number_of_bits < 10'd1023) begin //buffer space remains if ((CE_TOTAL > con_high) || (CO_TOTAL > con_high)) //If we have a "1" PN_code detected begin number_of_bits <= number_of_bits + 10'd1; //increment the bit counter output_buffer[number_of_bits] = 1'b1; //Set the output buffer to a 1 if we detected a 1 data_detect<=1'b1; end if ((CE_TOTAL < con_low) || (CO_TOTAL < con_low)) //If we have a "0" PN_code detected begin number_of_bits <= number_of_bits + 10'd1; //increment the bit counter output_buffer[number_of_bits] = 1'b0; //Set the output buffer to a 1 if we detected a 1 data_detect<=1'b1; end end //buffer space remains end //sequencer if(start_readout==1) begin readout_mode<=1'b1; end end //readout_mode=0 else begin //readout_mode = 1 readout_clk=readout_clk + 19'd1; if(result_counter < number_of_bits) begin //if there is still data to process if (readout_clk==19'd0) //22'd0 begin transmitnow <=1'b0; end if (readout_clk==19'd131072) begin case (output_buffer[result_counter]) 1'b0: begin tx_byte<=8'd48; transmitnow<=1'b1; end 1'b1: begin tx_byte<=8'd49; transmitnow<=1'b1; end endcase end if (readout_clk==19'd262144) begin result_counter=result_counter+10'd1; end end //if there is still data to process end //readout_mode = 1 end //reset =1 condition end //on clock endmodule