input wire[7:0]sbyte,//byte to be sent input wire send,//start sending on this impulse
output reg[7:0]rx_byte,//byte received output reg rx_start_bit,//mark RX start bit output reg rx_stop_bit,//mark RX stop bit
output reg rbyte_ready,//signal when rewceived byte is ready output reg tx,//serial transmitter (TX) line output reg busy,//transmitter is busy output reg tx_start_bit,//mark TX start bit output reg tx_stop_bit,//mark TX stop bit output reg test );
//скорость приема и передачи определяется этой константой //она рассчитана из исх. тактовой частоты 5Mhz и желаемой скорости 38400 //как 5000000/38400 = 130 parameter RCONST =128;
reg[10:0]cnt;
//счетчик длительности принимаемого бита always @(posedge clk5 or posedge reset) begin if(reset) cnt <=0; else begin if(cnt == RCONST || num_bits==0) cnt <=0; else cnt <= cnt +1'b1; end end
//приемник always @(posedge clk5 or posedge reset) begin if(reset) begin num_bits <=0; shift_reg <=0; end else begin //прием начинается когда RX падает в ноль if(num_bits==0&& rx==1'b0) num_bits <=10; else if(cnt == RCONST) num_bits <= num_bits -1'b1;
//фиксация принятого бита где-то посередине if(cnt == RCONST/2) shift_reg <={rx,shift_reg[8:1]}; end end always @* begin rbyte_ready = (cnt == RCONST)&(num_bits==1); rx_start_bit = (num_bits==10); rx_stop_bit = (num_bits==1); test = rx_start_bit | rx_stop_bit; end
//запоминаем принятый байт по окончании приема always @(posedge clk5 or posedge reset) if(reset) begin rx_byte <=0; end else begin if(rbyte_ready) rx_byte <= shift_reg[7:0]; end
always @(posedge clk5 or posedge reset) begin if(reset) begin send_reg <=0; send_num <=0; send_cnt <=0; end else begin //передача начинается по сигналу send if(send) send_cnt <=0; else if(send_time) send_cnt <=0; else send_cnt <= send_cnt +1'b1;
if(send) begin //загружаем передаваемый байт в сдвиговый регистр по сигналу send send_reg <={sbyte,1'b0}; send_num <=10; end else if(send_time && send_num!=0) begin //выдвигаем передаваемый байт send_reg <={1'b1,send_reg[8:1]}; send_num <= send_num -1'b1; end end end
always @* begin busy = (send_num!=0); tx_start_bit = (send_num==10); tx_stop_bit = (send_num==1); end
Подробнее...