verilog--实现数据的串并转换
并行转串行--用这个测试用例是最简单易懂的,这个测试用例需要使用使能信号端。当然还可以用计数器就稍微麻烦一点。
module parallel(clk, rst_n, en, din, dout);
input clk;
input rst_n;
input en;
input [7:0]din;
output dout;
reg dout;
reg [6:0]dout_1;
always@(posedge clk )begin
if(!rst_n)begin
{dout_1,dout} <=8'b0; //通过拼接符,可减少触发器端口数
end
else begin
if(en) begin
{dout_1,dout} <= din;
end
else begin
{dout_1,dout} <= {1'b0,dout_1};
end
end
end
endmodule
tb:
`timescale 1ns/1ps
module parallel_tb;
reg clk;
reg rst_n;
reg en;
reg [7:0]din;
wire dout;
parallel u1(
.clk(clk),
.rst_n(rst_n),
.en(en),
.din(din),
.dout(dout)
);
initial begin
clk=1'b1;
rst_n=1'b0;
en=1'b0;
#8;
rst_n=1'b1;
#2;
en=1'b1;
#10;
en=1'b0;
#70;
en=1'b1;
#10;
en=1'b0;
end
always #5 clk=~clk;
initial begin
#10;
din=8'b0110_1100;
#80;
din=8'b11110000;
#150;
$stop();
end
endmodule
串行转并行--每四位进行一次输出,并含有标志位,串转并:4bit一输出。可直接修改参数进行8bit一输出都可行。
module chuan_bing (
clk,rst_n,d_in,d_out,d_one
);
input clk;
input rst_n;
input d_in;
output [3:0]d_out;//输出4位
output d_one;//满四位输出标志
reg [1:0]cnt;
reg d_one;
reg d_one_1;
reg [3:0]d_out;
reg [3:0]d_out_1;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
d_out_1 <= 4'bx;
end
else begin
d_out_1[cnt] <= d_in;
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
d_out <= 4'b0;
end
else if (d_one_1) begin
d_out <= d_out_1;
d_one <= d_one_1;
end
else begin
d_out <= 4'b0;
d_one <= d_one_1;
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
cnt <= 2'b0;
d_one_1 <= 1'b0;
end
else if(cnt == 2'b11) begin
cnt <= 2'b0;
d_one_1 <= 1'b1;
end
else begin
cnt <= cnt + 1'b1;
d_one_1 <= 1'b0;
end
end
endmodule
tb:
`timescale 1ns/1ps
module chuan_bing_tb;
reg clk;
reg rst_n;
reg d_in;
wire [3:0]d_out;
wire d_one;
chuan_bing u1(
clk,rst_n,d_in,d_out,d_one
);
initial begin
clk = 1'b1;
rst_n = 1'b0;
#10;
rst_n = 1'b1;
end
always #5 clk = ~clk;
initial begin
repeat(16) begin
#10;
d_in = {$random}%2;
end
end
endmodule