原创 同学的一个“Verilog UART作业”作业,留着有用

2009-2-6 09:17 2465 5 5 分类: FPGA/CPLD

并转串——串转并


要求:并行输入1 byte,串行输出,无数据时输出高电平,输出格式1100+8bit+奇偶校验+0011(停止位)


串行输入,并行输出,检测是否奇偶校验错误,是否有帧传输错误


传输每bit数据占16个clock周期



//transmitter.v
module transmitter(in_clk,
                in_resetn,
                in_Data,
                in_DataEnable,
                out_NextData,
                out_Bit
                );
input in_clk;
input in_resetn;
input in_DataEnable;
input [7:0] in_Data;
output out_NextData;
output out_Bit;


parameter IDLE="16",STOP1=10,STOP2=11,STOP3=12,STOP4=13,START1=14,START2=15,START=1,D1=1,D2=2,D3=3,D4=4,D5=5,D6=6,D7=7,D8=8,PARITY=9;
reg [3:0] st, next_st;
reg [3:0] ClkCounter;
reg [8:0] StoredData;
reg out_NextData;
reg out_Bit;
reg oBit;


always @(posedge in_clk or negedge in_resetn)
if(!in_resetn)
    st <= IDLE;
else
    st <= next_st;


always @(posedge in_clk or negedge in_resetn)
   if(!in_resetn)
      ClkCounter <= 0;
   else
      ClkCounter <= ClkCounter + 1;


always @(ClkCounter or st or in_DataEnable)
   if(ClkCounter != 0)
       next_st =st;
   else
case(st)
    IDLE: if(in_DataEnable) next_st = STOP3;
    STOP3: next_st = STOP4;
    STOP4: next_st =START1;
    START1: next_st = START2;
    START2: next_st = D1;
    D1: next_st = D2;
    D2: next_st = D3;
    D3: next_st =D4;
    D4:next_st = D5;
    D5: next_st =D6;
    D6: next_st = D7;
    D7: next_st =D8;
    D8: next_st = PARITY;
    PARITY: next_st = STOP1;
    STOP1:next_st = STOP2;
    STOP2: next_st = STOP3;
    STOP3: next_st = STOP4;
    default: next_st = STOP3;
      endcase


always @(posedge in_clk or negedge in_resetn)
     if(!in_resetn)
        StoredData <= 0;
     else if(in_DataEnable)
        StoredData <= {in_Data,^in_Data};


always @(st or StoredData)
   case(st)
    IDLE: oBit="1";
        STOP1,STOP2: oBit = 0;
        STOP3,STOP4: oBit = 1;
        START1,START2:oBit = 0;
        D1:oBit = StoredData[8];
        D2:oBit = StoredData[7];
        D3:oBit = StoredData[6];
        D4:oBit = StoredData[5];
        D5:oBit = StoredData[4];
        D6:oBit = StoredData[3];
        D7:oBit = StoredData[2];
        D8:oBit = StoredData[1];
        PARITY:oBit = StoredData[0];
        default: oBit = 1;
    endcase
always @(posedge in_clk or negedge in_resetn)
if(!in_resetn)
    out_Bit <= 1;
else
    out_Bit <= oBit;

always @(st)
   if(st==STOP4)
      out_NextData =1;
   else
      out_NextData =0;


endmodule






//receiver.v
module receiver(in_clk,
              in_resetn,
              in_bit,
              out_Data,
              out_DataEnable,
              out_ParityError,
              out_FrameError
              );
input in_clk;
input in_resetn;
input in_bit;
output [7:0] out_Data;


output out_DataEnable;
output out_ParityError;
output out_FrameError;
reg [63:0] DetectSequence;
reg [3:0] ClkCounter;
reg [3:0] st, next_st;
reg [7:0] out_Data;
reg [7:0] store_data;
reg      Parity;
reg      Frame;
reg      out_DataEnable;
reg      out_ParityError;
reg      out_FrameError;


parameter IDLE="0", D1=1,D2=2,D3=3,D4=4,D5=5,D6=6,D7=7,D8=8,PARITY=9,STOP1=10,STOP2=11,STOP3=12,STOP4=13;


//detect
always @(posedge in_clk or negedge in_resetn)
   if(!in_resetn)
      DetectSequence <= 0;
   else
      DetectSequence <= { DetectSequence [62:0],in_bit};
assign DetectNewFrame = DetectSequence == 64'hFFFFFFFF00000000;


always @(posedge in_clk or negedge in_resetn)
   if(!in_resetn)
      ClkCounter <= 0;
   else if (DetectNewFrame)
      ClkCounter <= 0;
   else
      ClkCounter <= ClkCounter + 1'b1;


always @(posedge in_clk or negedge in_resetn)
   if(!in_resetn)
       st <= IDLE;
   else
       st <= next_st;


always @(ClkCounter or st or DetectNewFrame)
   if(ClkCounter != 0)
       next_st <= st;
   else
      case(st)
        IDLE: if (DetectNewFrame) next_st = D1;
        D1: next_st = D2;
        D2: next_st = D3;
        D3: next_st =D4;
        D4:next_st = D5;
        D5: next_st =D6;
        D6: next_st = D7;
        D7: next_st =D8;
        D8: next_st = PARITY;
        PARITY: next_st = STOP1;
        STOP1:next_st = STOP2;
        STOP2: next_st = STOP3;
        STOP3: next_st = STOP4;
        STOP4: next_st = IDLE;
        default: next_st = IDLE;
        endcase


always @(posedge in_clk or negedge in_resetn)
if(!in_resetn)
   begin
      out_Data=0;
      Parity="0";
      out_FrameError=0;
   end
else if(ClkCounter ==8)
    case(st)
      D1: store_data[7]=in_bit;
      D2: store_data[6]=in_bit;
      D3: store_data[5]=in_bit;
      D4: store_data[4]=in_bit;
      D5: store_data[3]=in_bit;
      D6: store_data[2]=in_bit;
      D7: store_data[1]= in_bit;
      D8:
         begin
         store_data[0]=in_bit;
         out_Data[7:0] = store_data[7:0];
        end
      PARITY: Parity="in"_bit;
      STOP1: if(!in_bit) out_FrameError =1;
               else out_FrameError = 0;
      STOP2: if(!in_bit) out_FrameError =1;
               else out_FrameError = 0;
      STOP3: if(in_bit) out_FrameError =1;
               else out_FrameError = 0;
      STOP4: if(in_bit) out_FrameError =1;
               else out_FrameError = 0;
    endcase


always @(st or in_bit or Parity or out_Data)
   if((st == STOP4) & (in_bit))
     begin
        out_DataEnable = 1;
        out_ParityError = (Parity != ^out_Data);
     end
   else
     begin
        out_DataEnable = 0;
        out_ParityError = 0;
     end
endmodule





//test.v
module testbench1();
   
reg Clk,Reset;
wire BitWire;
reg [3:0] ClkCounter;
reg in_DataEnable;
reg [7:0] in_Data;
wire [7:0] out_Data;


//connect transmitter and receiver
transmitter DUT1(.in_clk(Clk),
                 .in_resetn(Reset),
                 .in_Data(in_Data),
                 .in_DataEnable(in_DataEnable),
                 .out_NextData(NextData),
                 .out_Bit(BitWire)
                 );
receiver DUT2(.in_clk(Clk),
              .in_resetn(Reset),
              .in_bit(BitWire),
              .out_Data(out_Data),
              .out_DataEnable(out_DataEnable),
              .out_ParityError(out_ParityError),
              .out_FrameError(out_FrameErrror)
              );


initial
   begin
     $dumpfile("uart.vcd");
     $dumpvars;
     $dumpon;
     Clk = 1'b0;
     Reset = 1'b0;
     #100 Reset="1"'b1;
   end


always #5
   Clk <= !Clk;


always @(posedge Clk or negedge Reset)
   if(!Reset)
      ClkCounter <= 0;
   else
      ClkCounter <= ClkCounter + 1;


always @(posedge Clk or negedge Reset )
if(!Reset)
      begin
      in_Data=8'b0;
      in_DataEnable =1'b0;
      end
   else
   begin
   if((NextData) & (ClkCounter == 0))
     begin
     in_Data=$random;
     in_DataEnable =1'b1;
     $display("Issue data %h", in_Data);
     end
   else
     begin
     //in_Data=8'b0;
     in_DataEnable =1'b0;
     end
   end


always @(posedge Clk)
if(out_DataEnable)
begin
     if(out_ParityError)
        $display("Parity Error");
     else if (out_FrameErrror)
        $display("Frame Error");
     else
        $display("Receiver data %h", out_Data);
end


endmodule

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
5
关闭 站长推荐上一条 /3 下一条