verilog 직렬 변환 및 Modelsim 모방 실현

3641 단어 verilog직렬 통신
본문은 참고이다https://blog.csdn.net/vivid117/article/details/102021707이 문장은 후에 자신의 이해를 결합하여 수정한 것이다.

1. 모듈을 직렬로 변환


두 가지 방식으로 직렬과 변환을 실현할 수 있다. 하나는 위치 이동 레지스터이고, 다른 하나는 계수기이다. 여기는 위치 이동 레지스터만 사용하고, 계수기는 위의 블로그를 참고할 수 있다.
verilog 언어로 다음과 같이 설명합니다:data<={data[6:0],data in}
데이터는 8비트 출력 레지스터로, 이위 결합 문자의 변수 위치가 다르면 이위 방향이 다르다.
이번 직렬 변환은 위에서 언급한 블로그와 약간 다르게 출력 레지스터를 추가하여 출력을 잠그고 저장하여 위치를 이동하는 과정에서 데이터의 변화를 방지할 수 있다.
`timescale 1 ns/ 1 ns

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

reg [7:0] data;// 
reg [2:0] count;// , ,8 

// 
always@(posedge clk or negedge rst_n)
	begin
		if(rst_n==1'b0)
			count<=3'b0;
		else if(en==1)
			count<=count+3'b1;
	end

// 	
always@(posedge clk or negedge rst_n)
	begin
		if(rst_n==1'b0)
			data<=8'b0;
		else if(en==1'b1)
			data<={data[6:0],data_i};
	end

// 
always@(posedge clk or negedge rst_n)
	begin
		if(rst_n==1'b0)
			data_o<=8'b0;
		else if(rst_n==1'b1&&en==1'b1&&count==3'b111)
			data_o<=data;
	end
endmodule

해당하는 testbench는 다음과 같습니다.
`timescale 1 ns/ 1 ns
module serial2parallel_tb();

reg clk;
reg data_i;
reg en;
reg rst_n;
// wires                                              
wire [7:0]  data_o;                     
initial                                                
begin                                                  
	clk=1'b0;
	rst_n=1'b0;
	data_i=1'b0;
	en=1'b0;
	#10  rst_n=1'b1;
	#5	  en = 1'b1;
end


always #2 clk=~clk;
always #10 data_i = data_i+1'b1;// data_i 

serial2parallel s2p (
 
	.clk(clk),
	.data_i(data_i),
	.data_o(data_o),
	.en(en),
	.rst_n(rst_n)
);                                               
                                                  
endmodule

이testbench를 사용할 때 데이터i의 뒤집기 시간은 너무 작게 설정할 수 없습니다. 처음에 두 시계마다 한 번씩 뒤집기를 설정했는데 결과는 모의할 때 데이터o 한두 조의 데이터만 나오지만 데이터의 데이터는 정상입니다. 여기는 무슨 원인인지 모르겠습니다.

2. 병렬 모듈


그리고 직렬은 여전히 위치 이동 조작을 사용하여 완성되었다. 여기에 에너지 신호를 설정하여 에너지 신호가 에너지를 사용한 후에야 병렬 데이터를 수신할 수 있다.실제 응용에서 병렬 포트가 데이터를 계속 수신한다면, 직렬 포트는 항상 새로운 데이터의 가장 높은 위치를 보낼 것이다.예를 들어 첫 번째 시계가 왔을 때 0100 을 나란히 보냈다0001 이 8비트 데이터는 직렬 포트에서 8비트 데이터의 최고 0 을 즉시 출력하고 두 번째 시계가 오면 병렬 포트에서 00000001 이 8자리 데이터는 직렬 포트에서 이 8자리 데이터의 최고 0을 출력합니다. 이전 그룹의 최고 0이 아니라.만약 사능 신호에 가입한다면, 첫 번째 데이터 포트가 발송되기 전에 병렬 포트의 데이터를 받지 않을 수 있다.
`timescale 1ns/1ns

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

reg [7:0] data_buf;

always@(posedge clk or negedge rst_n)
begin
	if(rst_n==0)
		data_buf<=0;
	else if(en==1'b1)
		data_buf<=data_i;
	else
		data_buf<=data_buf<<1;
end

assign data_o=data_buf[7];

endmodule

Testbench는 다음과 같습니다.
`timescale 1 ns/1 ns

module parallel2serial_tb();

reg clk;
reg rst_n;
reg en;
reg [7:0] data_i;

wire data_o;

initial
begin
	clk=1'b0;
	en=1'b0;
   rst_n=1'b0;
	data_i=8'b01010101;
	#2	rst_n=1'b1;
	#4 en=1'b1;
	#8 en=1'b0;// , 01010101, 7 data_o 
	#10 data_i=8'b10110010;
	#102 en=1'b1;
	#106 en=1'b0;// , 10110010, 7 data_o 
end

always #2 clk=~clk;

parallel2serial p2s(
	.clk		(clk),
	.rst_n	(rst_n),
	.en		(en),
	.data_i	(data_i),
	.data_o	(data_o)
);
endmodule

testbench에서 두 개의 데이터를 설계했는데, 매번 en이 기능을 발휘할 때마다 데이터o 직렬 데이터의 가장 높은 위치를 즉시 출력합니다. (assign이 데이터 o와 데이터 buf를 직접 연결했기 때문입니다.) 엔이 더 이상 작동하지 않을 때까지, 엔이 더 이상 작동하지 않을 때 두 번째 시계가 오면 데이터o 높은 위치를 출력하고 순서대로 유추하기 때문에 모두 엔이 뒤에 있는 7개의 시계가 있어야만 데이터를 모두 출력할 수 있다.

좋은 웹페이지 즐겨찾기