为了准备今年的秋招,基础模块抓紧写起来.....
1、并串转化,原谅本渣渣,搞了好久,才调出来
2、需求分析
将并行数据转换成串行数据
3、开始写代码
端口说明: data_valid 指示数据是否有效
data 即为待转化数据
sda 即为串行输出数据
idle 为低时,说明数据正在输出,且输出sda有效
module p2s(
input wire clk,
input wire rst_n,
input wire [3:0] data,
input wire data_valid,
output reg idle,
output wire sda
);
reg [3:0] databuf;
reg [2:0] data_cnt;
reg start;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
databuf <= 4'b0;
start <= 1'b0;
end
else if (data_valid && data_cnt < 3'd3) begin
databuf <= data;
start <= 1'b1;
end
else begin
databuf <= databuf;
start <= 1'b0;
end
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
databuf <= 4'b0;
end
else if (start) begin
if(data_cnt < 3'd3)
databuf <= {databuf[2:0],1'bz};
end
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
idle <= 1'b1;
else if (data_cnt < 3'd3)
idle <= 1'b0;
else
idle <= 1'b1;
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
data_cnt <= 3'd0;
else if (start && data_cnt < 3'd3)
data_cnt <= data_cnt +1'b1;
else
data_cnt <= 3'd0;
end
assign sda = (idle == 1'b0) ?databuf[3] : 1'b1;
endmodule
4、开始写tb
`timescale 1ns/1ps
module tb_p2s();
reg clk;
reg rst_n;
reg [3:0] data;
reg data_valid;
wire idle;
wire sda_out;
integer i;
initial begin
clk =1'b0;
rst_n = 1'b0;
data_valid =1'b0;
//data = 4'b0;
#100;
rst_n = 1'b1;
data = 4'b1100;//{$random} % 16;
data_valid = 1'b1;
#40;
data =4'b1001;
#40;
data = 4'b0001;
#40;
data = {$random} % 16;
end
always #5 clk =~clk;
p2s p2s_inst(
.clk(clk),
.rst_n(rst_n),
.data(data),
.data_valid(data_valid),
.idle(idle),
.sda(sda_out)
);
endmodule
5、开始仿真

6、总结
并转串,需要将寄存数据移位输出。