ALTERA DE2 之 verilog HDL 学习笔记05-FPGA UART RS232

设计最简单的RS232通信逻辑,FPGA实现将接收到的数据会发出去,总共两个数据传输引脚,一收一发。将此通信模块分为三个部分:

1、波特率控制模块

2、发送模块。

3、接收模块

下面是代码部分:

//<span style="font-family: Arial, Helvetica, sans-serif;">Baud_Counter.v</span>
module Baud_Counter (
	// Inputs
input	clk,
input	reset,
input	reset_counters,

	// Outputs
output reg baud_clock_rising_edge,
output reg baud_clock_falling_edge,
output reg all_bits_transmitted
);

parameter BAUD_COUNTER_WIDTH = 9;
parameter BAUD_COUNT =  5;
parameter BAUD_TICK_COUNT =  BAUD_COUNT - 1; //9'd433;
parameter HALF_BAUD_TICK_COUNT	= BAUD_COUNT / 2; //9'd216;

parameter DATA_WIDTH = 9;
parameter TOTAL_DATA_WIDTH = DATA_WIDTH + 2;

reg [(BAUD_COUNTER_WIDTH - 1):0] baud_counter;
reg [3:0] bit_counter;

// control baud_counter
always @(posedge clk)
begin
	if (reset == 1'b1)
		baud_counter <= {BAUD_COUNTER_WIDTH{1'b0}};
	else if (reset_counters)
		baud_counter <= {BAUD_COUNTER_WIDTH{1'b0}};
	else if (baud_counter == BAUD_TICK_COUNT)
		baud_counter <= {BAUD_COUNTER_WIDTH{1'b0}};
	else
		baud_counter <= baud_counter + 1'b1;
end

// control baud_clock_rising_edge signal
always @(posedge clk)
begin
	if (reset == 1'b1)
		baud_clock_rising_edge <= 1'b0;
	else if (baud_counter == BAUD_TICK_COUNT)
		baud_clock_rising_edge <= 1'b1;
	else
		baud_clock_rising_edge <= 1'b0;
end

// control baud_clock_falling_edge signal
always @(posedge clk)
begin
	if (reset == 1'b1)
		baud_clock_falling_edge <= 1'b0;
	else if (baud_counter == HALF_BAUD_TICK_COUNT)
		baud_clock_falling_edge <= 1'b1;
	else
		baud_clock_falling_edge <= 1'b0;
end

// control bit counter
always @(posedge clk)
begin
	if (reset == 1'b1)
		bit_counter <= 4'h0;
	else if (reset_counters)
		bit_counter <= 4'h0;
	else if (bit_counter == TOTAL_DATA_WIDTH)
		bit_counter <= 4'h0;
	else if (baud_counter == BAUD_TICK_COUNT)
		bit_counter <= bit_counter + 4'h1;
end

// control all_bits_transmitted signal
always @(posedge clk)
begin
	if (reset == 1'b1)
		all_bits_transmitted <= 1'b0;
	else if (bit_counter == TOTAL_DATA_WIDTH)
		all_bits_transmitted <= 1'b1;
	else
		all_bits_transmitted <= 1'b0;
end

endmodule


//RS232_Out.v
module RS232_Out(
// Inputs
input clk,
input reset,
	
input [DATA_WIDTH:1] transmit_data,
input transmit_data_en,

// Outputs 
output reg serial_data_out,
output reg transmitting_data
);

parameter DATA_WIDTH = 8;
parameter BAUD_COUNT = 9'd434;

wire shift_data_reg_en, read_input_en;
//wire baud_clock;
wire all_bits_transmitted;

// debug outputs
//assign baud_clock = shift_data_reg_en;
//assign next_bit = data_out_shift_reg[0];

reg [DATA_WIDTH:0] data_out_shift_reg;

initial
begin
	serial_data_out <= 1'b1;
	data_out_shift_reg	<= {(DATA_WIDTH + 1){1'b1}}; // all ones
end

always @(posedge clk)
begin
	if (reset == 1'b1)
		serial_data_out <= 1'b1; 
	else
		serial_data_out <= data_out_shift_reg[0]; //next bit
end

always @(posedge clk)
begin
	if (reset == 1'b1)
		transmitting_data <= 1'b0;
	else if (all_bits_transmitted == 1'b1)
		transmitting_data <= 1'b0;
	else if (transmit_data_en)
		transmitting_data <= 1'b1;
end

always @(posedge clk)
begin
	if (reset == 1'b1)
		data_out_shift_reg	<= {(DATA_WIDTH + 1){1'b1}}; // all ones
	else if (read_input_en)
		data_out_shift_reg	<=  {transmit_data,1'b0};
	else if (shift_data_reg_en)
		data_out_shift_reg	<= 
			{1'b1, data_out_shift_reg[DATA_WIDTH:1]};
end


assign read_input_en = ~transmitting_data & ~all_bits_transmitted & transmit_data_en;

Baud_Counter Out_Counter (
// Inputs
.clk(clk), .reset(reset), .reset_counters(~transmitting_data),
// Outputs
.baud_clock_rising_edge(shift_data_reg_en),
.baud_clock_falling_edge(),
.all_bits_transmitted(all_bits_transmitted)
);
defparam
	Out_Counter.BAUD_COUNT = BAUD_COUNT,
	Out_Counter.DATA_WIDTH = DATA_WIDTH;

/*
Altera_UP_SYNC_FIFO RS232_Out_FIFO (
	// Inputs
	.clk			(clk),
	.reset			(reset),

	.write_en		(transmit_data_en & ~fifo_is_full),
	.write_data		(transmit_data),

	.read_en		(read_fifo_en),
	
	// Bidirectionals

	// Outputs
	.fifo_is_empty	(fifo_is_empty),
	.fifo_is_full	(fifo_is_full),
	.words_used		(fifo_used),

	.read_data		(data_from_fifo)
);
defparam 
	RS232_Out_FIFO.DATA_WIDTH	= DATA_WIDTH,
	RS232_Out_FIFO.DATA_DEPTH	= 128,
	RS232_Out_FIFO.ADDR_WIDTH	= 7;
*/
endmodule


//RA232_In.v
module RS232_In (
// Inputs
input clk,
input reset,
input serial_data_in,
input receive_data_en,
// Outputs
output reg [(DATA_WIDTH-1):0] received_data,
output reg receiving_data,
output reg data_received,
output baud_clock
);

parameter BAUD_COUNT = 9'd434;
parameter DATA_WIDTH = 8;
parameter TOTAL_DATA_WIDTH = DATA_WIDTH + 2;

wire shift_data_reg_en;
wire all_bits_received;


assign baud_clock = shift_data_reg_en;
reg [(TOTAL_DATA_WIDTH - 1):0]	data_in_shift_reg;
//reg receiving_data;
reg prev_receiving_data;



always @(posedge clk)
begin
	if (reset == 1'b1)
		receiving_data <= 1'b0;
	else if (all_bits_received == 1'b1)
		receiving_data <= 1'b0;
	else if (serial_data_in == 1'b0)
		receiving_data <= 1'b1;
end

always @(posedge clk)
begin
	prev_receiving_data  <= receiving_data;
	if (receiving_data==1'b1)
		data_received <= 1'b0;
	else if (prev_receiving_data==1'b1)
	begin
		data_received <= 1'b1;
		received_data <= data_in_shift_reg[DATA_WIDTH:1];
	end
end

always @(posedge clk)
begin
	if (reset == 1'b1)
		data_in_shift_reg	<= {TOTAL_DATA_WIDTH{1'b0}};
	else if (shift_data_reg_en)
		data_in_shift_reg	<= 
			{serial_data_in, data_in_shift_reg[(TOTAL_DATA_WIDTH - 1):1]};
end

Baud_Counter RS232_In_Counter (
// Inputs
.clk(clk),
.reset(reset),
.reset_counters(~receiving_data),
// Outputs
.baud_clock_rising_edge(),
.baud_clock_falling_edge(shift_data_reg_en),
.all_bits_transmitted(all_bits_received)
);
defparam 
	RS232_In_Counter.BAUD_COUNT= BAUD_COUNT,
	RS232_In_Counter.DATA_WIDTH= DATA_WIDTH;
/*
Altera_UP_SYNC_FIFO RS232_In_FIFO (
	// Inputs
	.clk			(clk),
	.reset			(reset),

	.write_en		(all_bits_received & ~fifo_is_full),
	.write_data		(data_in_shift_reg[(DATA_WIDTH + 1):1]),

	.read_en		(receive_data_en & ~fifo_is_empty),
	
	// Bidirectionals

	// Outputs
	.fifo_is_empty	(fifo_is_empty),
	.fifo_is_full	(fifo_is_full),
	.words_used		(fifo_used),

	.read_data		(received_data)
);
defparam 
	RS232_In_FIFO.DATA_WIDTH	= DATA_WIDTH,
	RS232_In_FIFO.DATA_DEPTH	= 128,
	RS232_In_FIFO.ADDR_WIDTH	= 7;
*/
endmodule




  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值