用Verilog实现串并转换

一、串转并转换模块

串转并就是将低3位信号和输入信号一起赋值。因为经过转换后,码元速率会将为原来四分之一,所以设置4分频时钟,将其输出。而并转串就是不断右移,取高位输出。

module serial_par(
    input clk,
    input d,
    output reg [3:0]q
);

//四分频模块
reg [13:0]cnt;
parameter N = 4;
reg clk_out;
always @(posedge clk)
begin
    if(cnt == N/2 - 1)begin
    	cnt <= 14'b0;
    	clk_out <= ~clk_out;
    end 
    else
	cnt <= cnt + 1'b1;
end

reg [3:0]data;
always @(posedge clk)
begin
    data <= {data[2:0],d};
end

always @(posedge clk_out)
begin
    q <= data;
end

endmodule

1) 利用移位寄存器

        串行转并行数据输出:采用位拼接技术(移位寄存器),将串行的数据总数先表示出来,然后发送一位数据加一,后面的接收的这样标志:
data_o <= {data_o[6:0],data_i };
1输入8输出 的 串转并模块的Verilog代码

module serial_parallel(
    input           clk,
    input           rst_n,en,
    input           data_i,   //一位输入
    output   reg [7:0] data_o	//8位并行输出
    );

always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0)
		data_o <= 8'b0;
	else if (en == 1'b1)
		data_o <= {data_o[6:0], data_i};	//低位先赋值
		//data_o <= {data_i,data_o[7:1],};	//高位先赋值
	else
		data_o <= data_o;
end

endmodule

 2)利用计数器

          利用计数器cnt 时钟计数,开始数据先给高位,每过一个时钟周期,数据便给低一位。这样便可以达到串转并的效果

1输入8输出 的 串转并模块的Verilog代码

module serial_parallel(
    input           clk,
    input           rst_n,
    input           data_i,
    output   reg [7:0] data_o
);

//msb first   most significant bit 表示二进制数据的最高位
reg     [2:0]   cnt; 	//计数器0-7  
always @(posedge clk or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        data_o <= 8'b0;
        cnt <= 3'd0;
    end
    else begin
        data_o[7 - cnt] <= data_i;	////高位先赋值
        cnt <= cnt + 1'b1;
    end
end

/*
//lsb first	(least significant bit) 表示二进制数据的最低位

reg     [2:0]   cnt;
always @(posedge clk or negedge rst_n)begin
    if(rst_n == 1'b0)begin
        data_o <= 8'b0;
        cnt <= 3'd0;
    end
    else begin
        data_o[cnt] <= data_i;   //低位先赋值
        cnt <= cnt + 1'b1;
    end
end
*/

endmodule

 二、并转串转换模块

en为输入有效脉冲,每四个脉冲输出高电平

module par_serial(
    input clk,
    input [3:0]d,
    input en,
    output q
);
reg[2:0]cnt;
always @(posedge clk)
begin
    if(cnt == 3)begin
        en <= 1;
        cnt <= 0;
    end
    else begin
        en <= 0;
        cnt <= cnt + 1'b1;
    end
end

reg[3:0]data;
always @(posedge clk)
begin
    if(en)
        data <= d;
    else 
        data <= data << 1;
end
assign q = data[3];

endmodule

并串转换的原理是:
先将八位数据暂存于一个四位寄存器器中,然后左移输出到一位输出端口,这里通过一个“移位”指令。

1)用寄存器移位实现,8输入1输出 的 并转串模块的Verilog代码

module parallel_serial(
clk, rst_n, en, data_i, data_o
    );
input clk, rst_n,en;
input [7:0] data_i;
output  data_o;

reg [7:0]  data_buf;
always @(posedge clk or negedge rst_i) begin
	if (rst_i == 1'b0) begin
		data_o <= 1'b0;
		data_buf <= 8'b0;
	end
	else if (en == 1'b1)
		data_buf <= data_i;
	else
		data_buf <= data_buf <<1; 	//将寄存器内的值左移,依次读出
		//data_buf <= {data_buf[6:0],1'b0};
end

assign data_o = data_buf[7];

endmodule

使能信号en表示开始执行并转串操作,由于并转串是移位操作,当一次并转串完成后,需要重新载入待转换的并行数据时,使能信号要再起来一次 

2)用计数器实现

module b_c(clk,rst_n,en,d,q);
input clk,rst_n;
input [3:0]d;
output reg en;
output reg q;

reg [3:0]count;
reg [3:0]data;
always @(posedge clk or negedge rst_n)
begin
    if(rst_n==0)
    begin
       count<=0;
       en<=0;;
       data<=d;
       q<=0;
    end
    else
    begin
       if(count<4)
       begin
           count<=count+1;
           en<=1;
           data<={data[2:0],data[3]};
           q<=data[3];
       end
       else
       begin
       count<=0;
       en<=0;
       q<=0;
       end
    end
end
endmodule

 

 

你可能感兴趣的:(FPGA经典设计)