Based on FPGA serial data to parallel data (Verilog)

Code:

module bit1_bit4(
    input    clk_50M_i,
	input    rst_n_i,
	
	input    data_i,
	input    data_en_i,
	
	output   [3:0]data_o,
	output   data_en_o
);
reg  data_i_tmp1;
reg  data_i_tmp2;
reg  data_en_i_tmp1;
reg  data_en_i_tmp2;

reg  [3:0]data_o_tmp;
reg       data_en_o_tmp; 
reg  [3:0]cnt; 

always@(posedge clk_50M_i or negedge rst_n_i)
	if(!rst_n_i)begin
	    data_i_tmp1    <= 1'b0;
	    data_i_tmp2    <= 1'b0;
		data_en_i_tmp1 <= 1'b0;
		data_en_i_tmp2 <= 1'b0;
	end
	else begin 
	    data_i_tmp1    <= data_i;
		data_i_tmp2    <= data_i_tmp1;
		data_en_i_tmp1 <= data_en_i;
		data_en_i_tmp2 <= data_en_i_tmp1;
	end
always@(posedge clk_50M_i or negedge rst_n_i)
	if(!rst_n_i)
	    data_o_tmp <= 4'b0;
	else if(data_en_i_tmp2)
	    data_o_tmp <= {data_o_tmp[2:0],data_i_tmp2};
	else
	    data_o_tmp <= 4'b0;
always@(posedge clk_50M_i or negedge rst_n_i)
    if(!rst_n_i)
	    cnt <= 4'b0;
	else if(data_en_i_tmp2)
	    cnt <= cnt + 1'b1;
	else
	    cnt <= 4'b0;
always@(posedge clk_50M_i or negedge rst_n_i)
	if(!rst_n_i)
	    data_en_o_tmp <= 1'b0;
	else if(cnt == 4-1)
	    data_en_o_tmp <= 1'b1;
	else
	    data_en_o_tmp <= 1'b0;

assign  data_o = data_o_tmp;	
assign  data_en_o = data_en_o_tmp; 	 
endmodule





test:

`timescale 1ns/1ns

module  bit1_bit4_tb();

parameter  clk_period = 20;

reg    clk_50M_i;
reg    rst_n_i;
reg    data_i;
reg    data_en_i;

initial begin
    clk_50M_i    = 1'b0;
    rst_n_i      = 1'b0;
	data_i       = 1'b0;
	data_en_i    = 1'b0;
	
    #100
	rst_n_i = 1'b1;
	   
	#200
	
    #clk_period data_i = 1'b1; data_en_i = 1'b1;
	#clk_period data_i = 1'b1;
	#clk_period data_i = 1'b0;
	#clk_period data_i = 1'b1;
	#clk_period                data_en_i = 1'b0;
	
	#200
	#clk_period data_i = 1'b0; data_en_i = 1'b1;
	#clk_period data_i = 1'b1;
	#clk_period data_i = 1'b1;
	#clk_period data_i = 1'b0;
	#clk_period                data_en_i = 1'b0;
	
	#200
	#clk_period data_i = 1'b1; data_en_i = 1'b1;
	#clk_period data_i = 1'b1;
	#clk_period data_i = 1'b1;
	#clk_period data_i = 1'b0;
	#clk_period                data_en_i = 1'b0;
	
	#200
	#clk_period data_i = 1'b0; data_en_i = 1'b1;
	#clk_period data_i = 1'b0;
	#clk_period data_i = 1'b0;
	#clk_period data_i = 1'b1;
	#clk_period                data_en_i = 1'b0;
	
	#200
	#clk_period data_i = 1'b1; data_en_i = 1'b1;
	#clk_period data_i = 1'b0;
	#clk_period data_i = 1'b0;
	#clk_period data_i = 1'b0;
	#clk_period                data_en_i = 1'b0;
	
end

always #(clk_period/2) clk_50M_i = ~clk_50M_i;

bit1_bit4  bit1_bit4_inst(
    .clk_50M_i(clk_50M_i),
	.rst_n_i(rst_n_i),
	
	.data_i(data_i),
	.data_en_i(data_en_i),
	
	.data_o(),
	.data_en_o()
);


endmodule

Simulation screenshot:
Insert picture description here

Note: I accidentally saw the data serial-to-parallel conversion on some blogs, which can basically be realized logically, but most of them cannot be used. There is no basic signal enable, timing beat, and the signal naming is very casual. The shift register is simply implemented, and the value of direct multiplexing is almost zero. That's why my two blogs were born. The time is relatively short, I will optimize it later when I have time, and hope to provide a standardized practical code idea for everyone to learn together

Guess you like

Origin blog.csdn.net/jiyishizhe/article/details/108779157
Recommended