一、串转并转换模块
串转并就是将低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
串行转并行数据输出:采用位拼接技术(移位寄存器),将串行的数据总数先表示出来,然后发送一位数据加一,后面的接收的这样标志:
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
利用计数器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