🔍See the article below for program acquisition methods
🔍The project includes complete programs, comments, references, and operation videos
⚡️Algorithm Simulation Effect Preview
The simulation test results using Vivado 2022.2 are as follows (217 convolution encoding and decoding Verilog development, without using IP cores):


🚀System Overview

1.16PSK
16-Phase Shift Keying (16PSK) is a digital modulation technique that transmits information by changing the phase of the carrier wave. 16PSK can transmit 4 bits of information in one symbol time, making it widely used in high-speed data transmission.
16PSK is a phase modulation technique where the phase of the carrier signal changes according to the information to be transmitted. In 16PSK, one symbol can represent 4 bits of information, meaning there are 16 different phase states for each symbol. The 16 states are evenly distributed on the unit circle, forming a 16-point constellation diagram.
2. Frame Synchronization
In digital communication, information is typically organized and transmitted in frames. The purpose of frame synchronization is to determine the starting position of each frame so that the receiver can correctly demodulate the data within each frame.
Assuming the frame structure sent is: frame synchronization code + information code sequence. The frame synchronization code is a specific sequence used by the receiver to identify the start of the frame.
The process of frame synchronization involves searching for positions in the received sequence that match the frame synchronization code. Once a matching position is found, the start of the frame is determined, and subsequent code elements can be correctly divided and processed according to the frame structure.
3. Convolutional Encoding and Viterbi Decoding
Convolutional encoding is a forward error correction coding method, particularly suitable for wireless communication and other applications with poor channel conditions. It primarily maps the information sequence into a more redundant codeword sequence using convolution operators. A typical convolutional encoder consists of two shift registers and an adder, following a specific generating polynomial for encoding.
Let the information sequence be u(n), and the two generating polynomials of the convolutional encoder be G1(D) and G2(D), then the encoding output v(n) can be expressed as:
v(n)=u(n)G1(D)+u(n−1)G2(D)+…
Here, D is the delay operator, and the actual expression depends on the specific choice of the order and coefficients of the generating polynomial.
Viterbi decoding is a dynamic programming algorithm used for maximum likelihood sequence estimation, widely applied in the decoding process of convolutional encoding and other sequence coding. In convolutional encoding, the Viterbi decoder constructs a tree structure called a “state transition graph” or “trellis” to find the most likely path of the original information sequence.
In the Viterbi decoding algorithm, each step requires calculating branch metrics, path metrics, and updating surviving paths, while also needing to know the state transition grid, timing control, and other information, as shown in the diagram:
Assuming the Viterbi decoder faces a received codeword sequence y(n) with noise, its goal is to minimize the Hamming distance or maximize the likelihood. The core of the Viterbi algorithm is to maintain the state probabilities at each step and the accumulated cost of the best path from the initial state to the current state.
State transition equation: For each time n and each state Sj, the best path accumulated cost C(n,Sk) for the next state Sk can be recursively expressed as the accumulated cost of all previous states Sj plus the corresponding path probability gain:
C(n,Sk)=Sj∈prev(Sk)min[C(n−1,Sj)+P(y(n)∣Sk)]
Where prev(Sk) represents the set of predecessor states of state Sk, and P(y(n)∣Sk) is the probability of observing y(n) given the current state Sk.
Termination state decision: At the end of decoding, the path corresponding to the termination state with the minimum accumulated cost is selected as the optimal solution, and backtracking this path yields the optimal decoding result.
✨Some Core Code
..//Convolutional Encoding
conv_217_code uut ( .i_clk (i_clkdx), .i_reset (i_rst), .i_en (i_en), .i_x (i_dat), .o_enc (o_enc) );
//Parallel to Serial Conversion p2s p2su( .i_clk2x (i_clkd2x), .i_reset (i_rst), .i_enc (o_enc), .o_enc (o_encs) );
reg signed[250:0] r1_bit; reg signed[250:0] r2_bit; always @(posedge i_clkd2x or posedge i_rst)begin if(i_rst) begin r1_bit <= 251'd0; r2_bit <= 251'd0; endelse begin r1_bit <= {r1_bit[249:0],o_enc[1]}; r2_bit <= {r2_bit[249:0],o_enc[0]}; endend wire signed[1:0] w_encs={r1_bit[157],r2_bit[157]};
T16PSK T16PSKU(.i_clkdx(i_clkd2x),.i_clksample(i_clk),.i_rst (i_rst),.i_en (i_en),.i_dat (o_encs),.o_ISET (o_ISET),.o_clk_3div(),.o_I16PSK (o_I16PSK),.o_Q16PSK (o_Q16PSK),.o_I16PSKs (o_I16PSKs),.o_Q16PSKs (o_Q16PSKs),.o_cos (),.o_sin (),.o_modc (),.o_mods (),.o_mod (o_mod_T));
//Add Channel awgns awgns_u( .i_clk(i_clk), .i_rst(i_rst), .i_SNR(i_SNR), // This can set the signal-to-noise ratio, values from -10 to 50, .i_din(o_mod_T[28:13]), .o_noise(), .o_dout(o_Nmod_T) );
////16QAM Demodulation wire o_en_dec;R16PSK R16PSKU(.i_clk (i_clkd2x),.i_clksample(i_clk),.i_rst (i_rst),.o_clk_3div(),.i_med (o_Nmod_T),.o_cos (),.o_sin (),.o_modc (o_modc_R),.o_mods (o_mods_R),.o_Ifir (o_Ifir_R),.o_Qfir (o_Qfir_R),.o_wbits(o_wbits),.o_bits (o_bits),.o_bits_head(o_bits_head),.o_peak(o_peak),.o_en_data(o_en_data),.o_en_pn(o_en_pn),.o_frame_start(o_frame_start),.o_en_dec(o_en_dec));
wire [1:0]o_encp; s2p s2pu( .i_clk (i_clkd2x), .i_reset (i_rst|o_frame_start), .i_en (o_en_data), .i_enc (o_bits), .o_enc (o_encp) );
//Viterbi Decoding reg[39:0]dly_start;always @(posedge i_clkdx or posedge i_rst)begin if(i_rst) begin dly_start <= 40'd0; endelse begin dly_start <= {dly_start[38:0],o_frame_start}; endendreg[299:0]dly_en;always @(posedge i_clkdx or posedge i_rst)begin if(i_rst) begin dly_en <= 300'd0; endelse begin dly_en <= {dly_en[298:0],o_en_dec}; endend
assign o_dec_enable = dly_en[267];
conv_217_decode conv_217_decodeu( .i_clk (i_clkdx), .i_reset (i_rst|o_en_pn), // .i_en (o_dec_enable), .i_enc (o_encp), .o_dec (o_dec) );
Error_Chech Error_Chech_u1( .i_clk(i_clkdx), .i_rst(i_rst), .i_trans(i_dat), .i_en_data(o_dec_enable), .i_rec(o_dec), .o_error_num(o_error_num), .o_total_num(o_total_num), .o_rec2 () );
endmodule0sj2_088m
🌐How to Obtain the Complete Project
Method 1: Copy the link into your browser
https://mbd.pub/o/bread/YZWXlJZxZg==
Method 2: Open the store and search:
http://www.store718.com/List.asp?ID=4742
Method 3: Click 【Read Full Article】 at the bottom left of the article

Method 4: If the above links are invalid, for program debugging bugs or project collaboration, you can contact via WeChat or QQ.
