OpenCores
URL https://opencores.org/ocsvn/blue/blue/trunk

Subversion Repositories blue

[/] [blue/] [trunk/] [blue8/] [rcvr.v] - Rev 4

Go to most recent revision | Compare with Previous | Blame | View Log

/*
    This file is part of Blue8.
 
    Foobar is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
 
    Foobar is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.
 
    You should have received a copy of the GNU Lesser General Public License
    along with Blue8.  If not, see <http://www.gnu.org/licenses/>.
 
    Blue8 by Al Williams alw@al-williams.com
 
*/
 
 `default_nettype none
 
// async receiver -- Williams
 
module rcvr (input wire clk,input wire clke,input wire rst,input wire rxd,
  output [7:0] dout, output reg data_ready, input wire rdn,output reg framing_error, output reg overrun_error);
//input clk;	  // main clock coming in
//input clke;   // 16x baud rate clock enable
//input rst;	  // reset
//input rxd;   // serial input
//output [7:0] dout;  // output bus
//output data_ready;	// high when data is ready  
//input rdn;          // put data on dout when high
//output framing_error;  // high if frame error occurs
//output overrun_error;  // detects overrun
//reg overrun_error;
 
 
reg rxd1;	 // these two used to sync incoming data
reg rxd2;
 
reg clk1xe;   // clock enable for 1x clock
reg clk1x_enable;     // generate the 1x receive clock (that is, character reception in progress)
reg [3:0] clkdiv=0;  // divide 16x clock to 1x clock
reg [7:0] rsr;		 // shift register
reg [7:0] rbr;		 // buffer register
reg [3:0] no_bits_rcvd;  // counter
 
assign dout = (rdn & !rst) ? rbr : 8'bz;   // data bus output
 
always @(posedge clk or posedge rst)	 // synchronize incoming signal
begin
if (rst)
begin
  rxd1 <= 1'b1;
  rxd2 <= 1'b1;
end
else 
if (clke)
begin
  rxd1 <= rxd;
  rxd2 <= rxd1;
end
end
 
always @(posedge clk or posedge rst)				// go to 1x clock  until 9 (include stop) bits read
begin
if (rst)
  clk1x_enable <= 1'b0;
else if (clke) 
  begin
    if (!rxd2 & !rxd1 & !rxd)			           // detect start bit
       clk1x_enable <= 1'b1;							  // turn on clk1x
    if (no_bits_rcvd == 4'b1010)				  // or if done (no_bits_rcvd only increments during rcv)
       clk1x_enable <= 1'b0;							  // turn off
  end
end
 
always @(posedge clk or posedge rst)	     // if rdn is 1 then clear data ready, set it when all bits read
 begin												  // note, the dout assign "uses" rdn
  if (rst)
     data_ready = 1'b0;
  else 
  begin
    if (rdn) data_ready = 1'b0;
    if (clke)
	   if (no_bits_rcvd == 4'b1010)
        data_ready = 1'b1;
  end
end 
 
always @(posedge clk or posedge rst)	    // generate 1x rate clock
begin
  if (rst)		
  begin
    clkdiv <= 4'b0000;
  end
  else 
  begin 
    if (clke)
	   if (clk1x_enable)
		begin 	
	    clkdiv<=clkdiv+1; 
      end
	   else 
		begin
	    clkdiv<=4'b1000;   // ensure correct delay after start bit
      end
  end
end
 
 
always @(posedge clk or posedge rst)		// generate 1x clock enable
begin
 if (rst) clk1xe=1'b0;
 else
   if (clke & clk1x_enable & clkdiv==4'b1111) clk1xe=1'b1; else clk1xe=1'b0;
end
 
 
 
always @(posedge clk or posedge rst)			  // depending on number of bits, take actions
if (rst)
begin
  rsr = 8'b0;
  rbr = 8'b0;
  framing_error = 1'b0;
  overrun_error = 1'b0;
end
else if (clk1xe)
begin
   if (no_bits_rcvd >= 4'b0000 && no_bits_rcvd <= 4'b1000) 	  // some # of bits until 8 bits
   begin
     rsr[6:0]=rsr[7:1];
     rsr[7] = rxd2;         // shift bits in LSB first
     if (no_bits_rcvd==4'b1000) 
	    begin
		   if (data_ready)
			  overrun_error=1'b1;
         else
			  begin
			  overrun_error=1'b0;
		     rbr=rsr;	  // copy shift register to data register
           end
       end
		 if ((no_bits_rcvd == 4'b1000) && (rxd2 != 1'b1))		 // check for framing error
         framing_error = 1'b1;
       else
         framing_error = 1'b0;
   end
end
 
 
always @(posedge clk or posedge rst)			 // count bits while 1x clock is running
if (rst)
  no_bits_rcvd = 4'b0000;
else 
  begin
  if (!clk1x_enable)							 // and reset count when 1x clock turns off
    no_bits_rcvd = 4'b0000;
  else
     if (clk1xe) no_bits_rcvd = no_bits_rcvd + 1;
 end
 
endmodule
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.