天天看點

verilog 基礎設計2 -并串轉化

為了準備今年的秋招,基礎子產品抓緊寫起來.....

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、開始仿真

verilog 基礎設計2 -并串轉化

6、總結

        并轉串,需要将寄存資料移位輸出。

繼續閱讀