4386|5

6892

帖子

0

TA的资源

五彩晶圆(高级)

楼主
 

verilog串口问题 [复制链接]

module my_232_rx(                                                              
                //input
       clk,
       RxD,
       rst,      
       //output
       RxD_data_b
       );
                 input           clk;// 50MHz主时钟
                 input           RxD;// RS232接收数据信号
                 input           rst;
       output          RxD_data_b;//接收数据寄存器,保存直至下一个数据来到                        
                 parameter       ClkFrequency = 50000000; //芯片时钟频率参数
                 parameter       Baud = 115200;  //波特率参数
                 parameter       Baud8 = Baud*8;
                 parameter       Baud8GeneratorAccWidth =16;
                 parameter       Baud8GeneratorInc = ((Baud<<(Baud8GeneratorAccWidth-4))+(ClkFrequency>>5))/(ClkFrequency>>4);
                 reg             [Baud8GeneratorAccWidth:0] Baud8GeneratorAcc;
       wire            Baud8Tick = Baud8GeneratorAcc[Baud8GeneratorAccWidth];
       reg             start;
       reg             [3:0]count;
       reg             [3:0]counter;
       reg             [3:0]state;
       reg             [4:0]bit_spacing;
       wire            next_bit=(bit_spacing==7)?1:0;
       reg     [7:0]RxD_data_a;
       wire    [7:0]RxD_data_b;
       assign          RxD_data_b=RxD_data_a;
always @(posedge clk)
   if(!rst)
     Baud8GeneratorAcc <=0;  
  else
     Baud8GeneratorAcc <= Baud8GeneratorAcc[Baud8GeneratorAccWidth-1:0] + Baud8GeneratorInc;
always @(posedge clk)
    if(!rst)
     begin
      count<=0;
      start<=0;
   end
  else if(Baud8Tick)
        begin
            if(state==4'b0000)  //判断是否为起始信号,若高于8次采样为低电平,则认为是有效的启动信号,低于则认为启动信号无效
                begin
                    if(RxD ==1)
                         begin
                             count<=count+1;
                                  if(count==7)
                                      begin
                                          count<=0;
                                          start<=1;
                                      end   
                          end
                     else
                        count<=0;
                 end
             else
                start<=0;
        end
always @(posedge clk)
     if(!rst)
         bit_spacing <= 4'b0000;
   else
        if(Baud8Tick)
            begin
                if(bit_spacing==15)
                     bit_spacing<=0;
                else
                   bit_spacing <= bit_spacing+1;
            end
always @(posedge clk)
     if(!rst)
      state<=0;
   else if(Baud8Tick)
         case(state)
            4'b0000: if(start)
                      state <= 4'b1000;  // start bit found?           
    4'b1000: if(next_bit)
                         begin
                            state <= 4'b1001;  // bit 0
                         end
            4'b1001: if(next_bit)
                         begin
                             state <= 4'b1010;  // bit 1
                         end
            4'b1010: if(next_bit)
                         begin
                             state <= 4'b1011;  // bit 2
                         end
            4'b1011: if(next_bit)
                         begin
                             state <= 4'b1100;  // bit 3
                         end
            4'b1100: if(next_bit)
                         begin
             state <= 4'b1101;  // bit 4
                         end
            4'b1101: if(next_bit)
                         begin
                             state <= 4'b1110;  // bit 5
         end
            4'b1110: if(next_bit)
                         begin
                             state <= 4'b1111;  // bit 6
                         end

            4'b1111: if(next_bit)
                         begin
                             state <= 4'b0001;  // bit 7
                         end
            4'b0001: if(next_bit)
                     state <= 4'b0000;  // stop bit
            default: state <= 4'b0000;
          endcase
always @(posedge clk)
    if(!rst)
     begin  
   RxD_data<= 8'b10101010;
   counter<=0;
     RxD_data_a<=8'b10101010;
   end
  else if(Baud8Tick && next_bit && state[3])
     begin  
   counter<=counter+1;
   RxD_data<= {RxD, RxD_data[7:1]};  
    if(counter==4'b1000)   
        begin
     RxD_data_a<=RxD_data;
      counter<=0;
     RxD_data<=0;
    end
   end  
endmodule
请大家分析一下上面的串口代码错误在哪里?
此帖出自FPGA/CPLD论坛

最新回复

這是我用的串口通信碼: `timescale 1ns / 1ps module serialfun(clk, RxD, TxD, GPout, GPin);input clk; input RxD;output TxD; output [7:0] GPout;input [7:0] GPin; ///////////////////////////////////////////////////wire RxD_data_ready;wire [7:0] RxD_data;async_receiver deserializer(.clk(clk), .RxD(RxD), .RxD_data_ready(RxD_data_ready), .RxD_data(RxD_data)); reg [7:0] GPout;always @(posedge clk) if(RxD_data_ready)  GPout <= RxD_data; ///////////////////////////////////////////////////async_transmitter serializer(.clk(clk), .TxD(TxD), .TxD_start(RxD_data_ready), .TxD_data(GPin)); endmodule   async_receiver, async_transmitter 可以在 http://www.fpga4fun.com/SerialInterface5.html 下載看到   以下是我寫的 testbench: `timescale 1ns / 1ps module serialfun_tb;   reg clk; reg RxD; reg [7:0] GPin;      wire TxD; wire [7:0] GPout; /*wire [7:0] RxD_data; wire RxD_data_ready; parameter Baud =115200; parameter ClkFrequency =27000000; parameter Baud8 = Baud*8; parameter Baud8GeneratorAccWidth = 16; parameter Baud8GeneratorInc = ((Baud8<<(Baud8GeneratorAccWidth-7))+(ClkFrequency>>8))/(ClkFrequency>>7); reg [Baud8GeneratorAccWidth:0] Baud8GeneratorAcc;*/ parameter clkper = 37;   serialfun uut (  .clk(clk),   .RxD(RxD),   .TxD(TxD),   .GPout(GPout),   .GPin(GPin) );  initial  begin  clk = 1;  RxD = 0;  GPin = 0; end   always begin  #(clkper);  clk <= ~clk; end   always begin  #5;  #100;  RxD <= ~RxD;  end  always begin  #10  GPin = 8'h01;  #10  GPin = 8'h02;  #10  GPin = 8'h04;  #10  GPin = 8'h08;  #10  GPin = 8'h10;  #10  GPin = 8'h20;  #10  GPin = 8'h40;  #10  GPin = 8'h80;  end       endmodule 不知道少了什麼, output都沒有東西? 謝謝    详情 回复 发表于 2010-6-28 10:17
点赞 关注
个人签名一个为理想不懈前进的人,一个永不言败人!
http://shop57496282.taobao.com/
欢迎光临网上店铺!
 

回复
举报

265

帖子

0

TA的资源

一粒金砂(高级)

沙发
 
这个?呵呵,自己先仿真一下
此帖出自FPGA/CPLD论坛
 
 

回复

5979

帖子

8

TA的资源

版主

板凳
 
呵呵 我是不想看了  发个我用的上来  和你的差不多

// RS-232 RX module
module async_receiver(clk, RxD, RxD_data_ready, RxD_data, RxD_endofpacket, RxD_idle);
input clk, RxD;
output RxD_data_ready;  // onc clock pulse when RxD_data is valid
output [7:0] RxD_data;

parameter ClkFrequency = 1000000;    // 10MHz时钟
//parameter ClkFrequency = 10000000;
parameter Baud = 115200;              //波特率设置115200

output RxD_endofpacket;  // one clock pulse, when no more data is received (RxD_idle is going high)
output RxD_idle;         // no data is being received


//波特率产生(我们采用8倍的过采样率)
parameter Baud8 = Baud*8;
parameter Baud8GeneratorAccWidth = 16;
wire [Baud8GeneratorAccWidth:0] Baud8GeneratorInc = ((Baud8<<(Baud8GeneratorAccWidth-7))+(ClkFrequency>>8))/(ClkFrequency>>7);
reg [Baud8GeneratorAccWidth:0] Baud8GeneratorAcc;

always @(posedge clk)
     Baud8GeneratorAcc <= Baud8GeneratorAcc[Baud8GeneratorAccWidth-1:0] + Baud8GeneratorInc;

wire Baud8Tick = Baud8GeneratorAcc[Baud8GeneratorAccWidth];

//同步RxD信号
reg [1:0] RxD_sync_inv;
always @(posedge clk)
             if(Baud8Tick) RxD_sync_inv <= {RxD_sync_inv[0], ~RxD};
// we invert RxD, so that the idle becomes "0", to prevent a phantom character to be received at startup

reg [1:0] RxD_cnt_inv;
reg RxD_bit_inv;

//对开始信号Start进行检测
always @(posedge clk)
if(Baud8Tick)
begin
        if( RxD_sync_inv[1] && RxD_cnt_inv!=2'b11) RxD_cnt_inv <= RxD_cnt_inv + 2'h1;
        else
        if(~RxD_sync_inv[1] && RxD_cnt_inv!=2'b00) RxD_cnt_inv <= RxD_cnt_inv - 2'h1;

        if(RxD_cnt_inv==2'b00) RxD_bit_inv <= 1'b0;
        else
        if(RxD_cnt_inv==2'b11) RxD_bit_inv <= 1'b1;
end

reg [3:0] state;
reg [3:0] bit_spacing;

// "next_bit" controls when the data sampling occurs
// depending on how noisy the RxD is, different values might work better
// with a clean connection, values from 8 to 11 work

wire next_bit = (bit_spacing==4'd10);

always @(posedge clk)
if(state==0)
        bit_spacing <= 4'b0000;
else
if(Baud8Tick)
        bit_spacing <= {bit_spacing[2:0] + 4'b0001} | {bit_spacing[3], 3'b000};

//一旦检测到"开始位",使用如下的状态机可以检测出接收到每一位数据
always @(posedge clk)
if(Baud8Tick)
case(state)
        4'b0000: if(RxD_bit_inv) state <= 4'b1000;  // start bit found?
        4'b1000: if(next_bit) state <= 4'b1001;  // bit 0
        4'b1001: if(next_bit) state <= 4'b1010;  // bit 1
        4'b1010: if(next_bit) state <= 4'b1011;  // bit 2
        4'b1011: if(next_bit) state <= 4'b1100;  // bit 3
        4'b1100: if(next_bit) state <= 4'b1101;  // bit 4
        4'b1101: if(next_bit) state <= 4'b1110;  // bit 5
        4'b1110: if(next_bit) state <= 4'b1111;  // bit 6
        4'b1111: if(next_bit) state <= 4'b0001;  // bit 7
        4'b0001: if(next_bit) state <= 4'b0000;  // stop bit
        default: state <= 4'b0000;
endcase

//使用一个移位寄存器来存储接受到的数据
reg [7:0] RxD_data;
always @(posedge clk)
if(Baud8Tick && next_bit && state[3]) RxD_data <= {~RxD_bit_inv, RxD_data[7:1]};

reg RxD_data_ready, RxD_data_error;
always @(posedge clk)
begin
        RxD_data_ready <= (Baud8Tick && next_bit && state==4'b0001 && ~RxD_bit_inv);  // ready only if the stop bit is received
        RxD_data_error <= (Baud8Tick && next_bit && state==4'b0001 &&  RxD_bit_inv);  // error if the stop bit is not received
end

reg [4:0] gap_count;
always @(posedge clk)
      if (state!=0) gap_count<=5'h00;
                else if (Baud8Tick & ~gap_count[4]) gap_count <= gap_count + 5'h01;

assign RxD_idle = gap_count[4];

reg RxD_endofpacket;

always @(posedge clk)
        RxD_endofpacket <= Baud8Tick & (gap_count==5'h0F);

endmodule
此帖出自FPGA/CPLD论坛

赞赏

1

查看全部赞赏

个人签名生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙
===================================
做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
 
 
 

回复

17

帖子

0

TA的资源

一粒金砂(初级)

4
 
樓上的請問一下
小弟我剛學,怎麼寫verilog testbench (ISIM), 我把clk 設定每個周期20ns, RxD 設定每10ns high, 10ns low...為什麼這樣我得不到RxD_data, 都一直是xxxxxxxx, 可以指教一下我該如何改? 謝謝
此帖出自FPGA/CPLD论坛
 
 
 

回复

5979

帖子

8

TA的资源

版主

5
 
把测试文件发上来
此帖出自FPGA/CPLD论坛
个人签名生活就是油盐酱醋再加一点糖,快活就是一天到晚乐呵呵的忙
===================================
做一个简单的人,踏实而务实,不沉溺幻想,不庸人自扰
 
 
 

回复

17

帖子

0

TA的资源

一粒金砂(初级)

6
 

這是我用的串口通信碼:

`timescale 1ns / 1ps

module serialfun(clk, RxD, TxD, GPout, GPin);
input clk;

input RxD;
output TxD;

output [7:0] GPout;
input [7:0] GPin;

///////////////////////////////////////////////////
wire RxD_data_ready;
wire [7:0] RxD_data;
async_receiver deserializer(.clk(clk), .RxD(RxD), .RxD_data_ready(RxD_data_ready), .RxD_data(RxD_data));

reg [7:0] GPout;
always @(posedge clk)
if(RxD_data_ready)
 GPout <= RxD_data;

///////////////////////////////////////////////////
async_transmitter serializer(.clk(clk), .TxD(TxD), .TxD_start(RxD_data_ready), .TxD_data(GPin));


endmodule

 

async_receiver, async_transmitter 可以在 http://www.fpga4fun.com/SerialInterface5.html 下載看到

 

以下是我寫的 testbench:

`timescale 1ns / 1ps

module serialfun_tb;

 
 reg clk;
 reg RxD;
 reg [7:0] GPin;
     
 wire TxD;
 wire [7:0] GPout;
 /*wire [7:0] RxD_data;
 wire RxD_data_ready;
 parameter Baud =115200;
 parameter ClkFrequency =27000000;
 parameter Baud8 = Baud*8;
 parameter Baud8GeneratorAccWidth = 16;
 parameter Baud8GeneratorInc = ((Baud8<<(Baud8GeneratorAccWidth-7))+(ClkFrequency>>8))/(ClkFrequency>>7);
 reg [Baud8GeneratorAccWidth:0] Baud8GeneratorAcc;*/
 parameter clkper = 37;
  
 serialfun uut (
  .clk(clk),
  .RxD(RxD),
  .TxD(TxD),
  .GPout(GPout),
  .GPin(GPin)
 );
 
 initial
 begin
  clk = 1;
  RxD = 0;
  GPin = 0;
 end
  
 always
 begin
  #(clkper);
  clk <= ~clk;
 end
  
 always
 begin
  #5;
  #100;
  RxD <= ~RxD;
  end

 always
 begin
  #10
  GPin = 8'h01;
  #10
  GPin = 8'h02;
  #10
  GPin = 8'h04;
  #10
  GPin = 8'h08;
  #10
  GPin = 8'h10;
  #10
  GPin = 8'h20;
  #10
  GPin = 8'h40;
  #10
  GPin = 8'h80;
  end  
    
endmodule

不知道少了什麼, output都沒有東西? 謝謝

 

此帖出自FPGA/CPLD论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表