完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
嗨,
我写了下面的uart接收器,但我无法从输入“rx”中删除所有噪声; 我使用了去抖动器和移动平均器,但是,下面的uart接收器有时候无法接收到正确的字节。 下面的示例将其参数CLOCKCYCLESPERBIT设置为868,如果使用100 MHz时钟,则为每位的时钟周期数。 请帮助解决从输入信号中消除噪声的最佳方法。 模块uartreceiver( 输入clk, 输入rx, 输出reg收到, 输出reg [8 -1:0]数据 ); 参数CLOCKCYCLESPERBIT = 868; 参数LOG2CLOCKCYCLESPERBIT = 10; //使用的值 //寄存器rxstate。 //接收器正在等待 //在传输上 参数RXIDLE = 0; //接收器正在接收比特。 参数RXRECEIVE = 1; // Receiver正在检查 //传输结束 参数RXSTOP = 2; //注册哪个持有 //接收者的状态 reg [2 -1:0] rxstate; //注册将用于保留 //计数时钟周期数。 reg [LOG2CLOCKCYCLESPERBIT -1:0]计数器; //注册使用的 //跟踪号码 //留下来接收的比特。 reg [3 -1:0] bitcount; 总是@(posedge clk)开始 //启用寄存器时钟 //只为每一点 if(counter == CLOCKCYCLESPERBIT)开始 if(rxstate == RXRECEIVE)开始 //在最后一点接收, //“bitcount”将为0,并且 //将自动重置 //减少时为7。 位计数 以上来自于谷歌翻译 以下为原文 Hi, I have written the following uart receiver, but I am not able to remove all noise from the input "rx"; I have used a debouncer and a moving average, but still, the following uart receiver sometime fail to receive the correct byte. The example below has its parameter CLOCKCYCLESPERBIT set to 868, which is the number of clock cycles per bit if a 100 MHz clock is used. Please help on what is the best way to remove noise from an input signal. module uartreceiver(input clk,input rx,output reg received,output reg[8 -1 : 0] data);parameter CLOCKCYCLESPERBIT = 868;parameter LOG2CLOCKCYCLESPERBIT = 10;// Values used with// the register rxstate.// Receiver is waiting// on a transmission.parameter RXIDLE = 0;// Receiver is receiving bits.parameter RXRECEIVE = 1;// Receiver is checking for// the end of a transmission.parameter RXSTOP = 2;// Register which hold// the state of the receiver.reg[2 -1 : 0] rxstate;// Register that will be used to keep// a count of the number of clock cycles.reg[LOG2CLOCKCYCLESPERBIT -1 : 0] counter;// Register which is used// to keep track of the number// of bits left to receive.reg[3 -1 : 0] bitcount;always @(posedge clk) begin// Enable clocking of registers// only for every bit.if (counter == CLOCKCYCLESPERBIT) beginif (rxstate == RXRECEIVE) begin// At the last bit to receive,// "bitcount" will be 0, and// will be automatically reset// to 7 when decremented.bitcount <= bitcount - 1'b1;// Logic that store each bit.data <= {rx, data[7:1]};endif (rxstate == RXIDLE) begin// I get here if the receiver// is in an idle state.// I check for the start// of a transmission.// A change of the incoming// serial line state to low// indicate the start of// a transmission.if (!rx) rxstate <= RXRECEIVE;received <= 0;end else if (rxstate == RXSTOP) begin// If I get here,// I expect a stop bit// which correspond to// the incoming serial// line being high.if (rx) received <= 1;// I set the receiver state// to iddle so as to wait// for the next transmission.rxstate <= RXIDLE;end else begin// At the last bit to receive,// I set the receiver state// so as to expect a stop bit.if (!bitcount) rxstate <= RXSTOP;endcounter <= 0;end else counter <= counter + 1'b1;endendmodule |
|
相关推荐
7个回答
|
|
None
以上来自于谷歌翻译 以下为原文 Thank you guys for all the inputs :-) I came up with a very robbust uart receiver; I get no receiption errors regardless of whether I use a debouncer on the "rx" input to remove noise :-) I especially thank Avrum on its tips on sampling past the start of each bits, and tips from all of you guys on synchronizing the receiver every bits :-) To respond to Bob, I have no reset input or error reporting output to keep it very simple; the receiver and transmitter will settle to a known state after a known number of clock cycles that I have commented on how to calculate. Below you will see the full source code for the receiver and transmitter; It is well commented on how to set the "clock cycle per bit" macro based on your clock speed and the bitrate(baudrate) that you want. I hope it helps someone else :-) UART RECEIVER // Module implementing a uart receiver.// The following implementation// follow rs232 standard signalling// with the following properties:// // - Expect to receive 8 data bits;// no parity bits.// - Receive least significant bit first.// - Expect to receive at least 1 stop bit;// will not check or fail if there is// more than 1 stop bit.// // An 8 bits data transmission begin// with a start bit which is a logic low// state of the data line, followed by// the 8 bits to transmit and terminated// by 1 or more stop bits which are logic// high states of the data line.// The following macros// definition must fall-through// when inserting this file.// // CLOCKCYCLESPERBIT:// This macro define the number// of clock cycles per bit.// Given the bitrate and clock// speed, it is calculated using// the following formula:// ((clockspeed/bitrate) + ((clockspeed/bitrate)/10/2));// where the expression ((clockspeed/bitrate)/10/2)// is the clock cycles amount that insure// that the receiver will sample past// the start of each bit.// Note that, as the receiver go through// its idle state to start receiving// the next byte, any accumulated// skew from the beginning of a bit// get discarded as the receiver// detect the exact beginning of a bit.// ei: For a clockspeed of 100Mhz// and a bitrate of 115200, the// above formula would yield 910.458;// the value of this macro is then// picked as: 910 or 911.// The value of this macro// should never be 0. ei:// `define CLOCKCYCLESPERBIT 911// // To change the name of the module,// a macro having the name of the module,// all lowercase, should fall-through// when inserting this file; the value// of the macro will be used as the name// of the module.// Description of the ports.// // input clk// Clock signal.// // input rx// Incoming serial line.// // output received// This signal become high// to indicate that a byte// has been received.// This signal is high// for one clock cycle.// // output[8] data// Byte value received.// Its value is valid only while// the output "received" is high.// // To skip unknown states on// the output "received", after// poweron this module must be run// for a clock cycle count of at least// (10 * $CLOCKCYCLESPERBIT), with// the input "rx" set high; unknown// states get flushed out of the module.module uartreceiver(input clk,input rx,output reg received,output reg[8 -1 : 0] data);// Note that there is no// output signal reporting// whether the module is// receiving, because// reception activities// can be assumed occuring// if the input "rx" is// changing state.parameter CLOCKCYCLESPERBIT = 911;parameter LOG2CLOCKCYCLESPERBIT = 10;// Values used with// the register rxstate.// Receiver is waiting// on a transmission.parameter RXIDLE = 0;// Receiver is receiving bits.parameter RXRECEIVE = 1;// Receiver is checking for// the end of a transmission.parameter RXSTOP = 2;// Register which hold// the state of the receiver.reg[2 -1 : 0] rxstate;// Register that will be used to keep// a count of the number of clock cycles.reg[LOG2CLOCKCYCLESPERBIT -1 : 0] counter;// Register which is used// to keep track of the number// of bits left to receive.reg[3 -1 : 0] bitcount;always @(posedge clk) begin// Logic updating the// register counter.if (rxstate == RXIDLE || counter == (CLOCKCYCLESPERBIT -1)) counter <= 0;else counter <= counter + 1'b1;// Enable clocking of registers// only for every bit.if (counter == (CLOCKCYCLESPERBIT -1) && rxstate == RXRECEIVE) begin// At the last bit to receive,// "bitcount" will be 0, and// will be automatically reset// to 7 when decremented.bitcount <= bitcount - 1'b1;// Logic that store each bit.data <= {rx, data[7:1]};endif (rxstate == RXIDLE) begin// I get here if the receiver// is in an idle state.// I check for the start// of a transmission.// A change of the incoming// serial line state to low// indicate the start of// a transmission.if (!rx) rxstate <= RXRECEIVE;received <= 0;// Enable clocking of registers// only for every bit.end else if (counter == (CLOCKCYCLESPERBIT -1)) beginif (rxstate == RXSTOP) begin// If I get here,// I expect a stop bit// which correspond to// the incoming serial// line being high.if (rx) received <= 1;// I set the receiver state// to iddle so as to wait// for the next transmission.rxstate <= RXIDLE;end else begin// At the last bit to receive,// I set the receiver state// so as to expect a stop bit.if (!bitcount) rxstate <= RXSTOP;endendendendmodule UART TRANSMITTER // Module implementing a uart transmitter.// The following implementation// follow RS232 standard signalling// with the following properties:// // - Expect to send 8 data bits;// no parity bits.// - Send least significant bit first.// - Transmit 2 stop bits.// // An 8 bits data transmission begin// with a start bit which is a logic low// state of the data line, followed by// the 8 bits to transmit and terminated// by 1 or more stop bits which are logic// high states of the data line.// The following macros// definition must fall-through// when inserting this file.// // CLOCKCYCLESPERBIT:// This macro define the number// of clock cycles per bit.// Given the bitrate and clock// speed, it is calculated using// the following formula:// (clockspeed/bitrate);// The result of the above formula// should be rounded-down, because// it is better to have a slightly// lower estimation of the duration// of a bit, this way a receiver// is guarantied to always sample// past the beginning of each bit,// and not fall short by sampling// the same bit twice.// ei: For a clockspeed of 100Mhz// and a bitrate of 115200, the// above formula would yield 867.056;// the value of this macro is then// picked as: 867.// The value of this macro// should never be 0. ei:// `define CLOCKCYCLESPERBIT 867// // To change the name of the module,// a macro having the name of the module,// all lowercase, should fall-through// when inserting this file; the value// of the macro will be used as the name// of the module.// Description of the ports.// // input clk// Clock signal.// // output tx// Outgoing serial line.// // input transmit// This signal is set high to// start trasmitting the byte// value on the input "data".// It must be kept high until// a negative edge on the output// "dataneeded" occur, which// mean that the byte value on// the input "data" has been// captured for transmission.// This signal can be continuously// held high to keep transmitting// the byte value on the input// "data"; the next value to transmit// must be set on the input "data"// as soon as the output "dataneeded"// become high; in fact the output// "dataneeded" will remain high// for a clock cycle count of at// least (2 * $CLOCKCYCLESPERBIT).// // input[8] data// Byte value to transmit// through the output "tx".// The byte value is captured// for transmission when the input// "transmit" is high and the output// "dataneeded" is high; hence the// next value to transmit must be set// as soon as the output "dataneeded"// become high; in fact the output// "dataneeded" will remain high// for a clock cycle count of at// least (2 * $CLOCKCYCLESPERBIT).// // output dataneeded// When this signal become high,// the byte value to transmit// must be set on the input "data".// This signal remain high for// a clock cycle count of at// least (2 * $CLOCKCYCLESPERBIT).// // To skip unknown states on// the output "tx", after poweron// this module must be run for// a clock cycle count of at least// (10 * $CLOCKCYCLESPERBIT), with// the input "transmit" set low;// unknown states get flushed out// of the module.module uarttransmitter(input wire clk,output reg tx,input wire transmit,input wire[8 -1 : 0] data,output wire dataneeded);// Note that there is no// output signal reporting// whether the module is// transmitting, because// transmission activities// can be assumed occuring// if the output "tx" is// changing state.parameter CLOCKCYCLESPERBIT = 867;parameter LOG2CLOCKCYCLESPERBIT = 10;// Values used with// the register txstate.// Transmitter is either// sending stop bits, or// waiting for the input// "transmit" to become high// to begin transmitting the// byte on the input data.parameter TXIDLE = 0;// Transmitter is// sending data bits.parameter TXSEND = 1;// Register which hold the// state of the transmitter.reg txstate;assign dataneeded = (txstate == TXIDLE);// Register that will be used to keep// a count of the number of clock cycles.reg[LOG2CLOCKCYCLESPERBIT -1 : 0] counter;// Register which will hold// the bits to transmit,// clocked in from// the input "data".reg[8 -1 : 0] bitstotransmit;// Register which is used// to keep track of the number// of bit left to send.reg[3 -1 : 0] bitcount;always @(posedge clk) begin// Enable clocking of registers// only for every bit.if (counter == (CLOCKCYCLESPERBIT -1)) beginif (txstate == TXIDLE) begin// The transmitter remain// in this state until the// input signal "transmit"// become high to begin// transmitting.// If bitcount is true,// I send stop bits for// the amount in bitcount.if (bitcount) beginbitcount <= bitcount - 1'b1;tx <= 1;end else if (transmit) begintxstate <= TXSEND;bitstotransmit <= data;// I send start bit.tx <= 0;bitcount <= 7;endend else begin// I transmit bitstotransmit[0].tx <= bitstotransmit[0];if (bitcount) beginbitcount <= bitcount - 1'b1;// I select the next// bit to transmit.bitstotransmit <= bitstotransmit >> 1'b1;end else begintxstate <= TXIDLE;// I set bitcount// to 2 in order to// send 2 stop bits.bitcount <= 2;endendcounter <= 0;end else counter <= counter + 1'b1;endendmodule View solution in original post |
|
|
|
我使用的是波特率:115200。我使用以下公式计算参数CLOCKCYCLESPERBIT :( clockspeed / baudrate);
ei:对于100 MHz的时钟速度,我得到:100000000/115200 == 868;我现在正在考虑Avrum对正确采样的建议进行代码更改。 以上来自于谷歌翻译 以下为原文 I am using a baudrate of: 115200. I calculate the parameter CLOCKCYCLESPERBIT using the following formular: (clockspeed / baudrate); ei: for a 100 MHz clockspeed I get: 100000000 / 115200 == 868; I right now making code changes considering Avrum suggestions on correct sampling. |
|
|
|
在进行编码更改时,如果两个状态位在同一时钟边沿上“看到”'rx'接收位的不同逻辑电平,请考虑2位状态机会发生什么。
从器件输入引脚到状态位的“rx”互连延迟不为零,并且不均匀。 在某种程度上,每个状态位的引脚 - >状态位寄存器延迟不一致,这就是破坏状态机的机会之窗。 我同意Avrum的评论。 对此,我补充说:你应该了解异步串行接口的工作原理。 有关异步串行接口和UART设计的大量信息和教程以及示例。 你应该首先尝试理解这个简单的接口,然后设计一个接收器和发射器。 就目前而言,您已经在了解接收到的内容之前设计了接收器,这完全是成功设计的相反顺序。 示波器可以帮助您了解您遇到的问题的性质,并希望能够引导您找到正确的问题来询问您的设计。 编码风格的另一个问题是:您的状态机无法自我纠正错误。 除非你是比这个星球上任何其他人更好的代码编写者,否则你可以通过编写检测并从非法状态或非法状态转换中恢复的代码来帮助自己。 最后一项:您的代码是否包含复位或初始化脉冲以启动处于IDLE状态的状态机? 如果FPGA通过rx输入上的稳定且无限的输入字符流启动,那么状态机是否会以一致且功能的方式运行? 祝你好运。 这个UART设计有望教你很多。 - 鲍勃埃尔金德 签名:新手的自述文件在这里:http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369总结:1。 阅读手册或用户指南。 你读过手册了吗? 你能找到手册吗?2。 搜索论坛(并搜索网页)以寻找类似的主题。 不要在多个论坛上发布相同的问题。 不要在别人的主题上发布新主题或问题,开始新的主题!5。 学生:复制代码与学习设计不同.6“它不起作用”不是一个可以回答的问题。 提供有用的详细信息(请与网页,数据表链接).7。 您的代码中的评论不需要支付额外费用。 我没有支付论坛帖子的费用。 如果我写一篇好文章,那么我一无所获。 以上来自于谷歌翻译 以下为原文 While you are making your coding changes, consider what would happen to your 2-bit state machine if the two state bits "saw" a different logic level for the 'rx' receive bit, on the same clock edge. The interconnect delay for 'rx' from the device input pin to the state bits is not zero, and it is not uniform. To the extent that pin -> state bit register delay is not uniform for each of the state bits, that is the window of opportunity for corrupting your state machine. I agree with Avrum's comments. To this I add: you should understand how async serial interface works. There is an abundance of information and tutorials and examples for async serial interfaces and UART designs. You should try to understand this simple interface first, THEN design a receiver and transmitter. As it stands, you have designed the receiver before understanding what you are receiving, and that is entirely the reverse order for successful design. An oscilloscope would help show you the nature of the problems you were having, and hopefully that would have guided you to the right questions to ask of your design. Another matter of coding style: your state machine does not self-correct for errors. Unless you are a much better writer of code than practically anyone else on the planet, you would help yourself by writing code that detects and recovers from either illegal states or illegal state transitions. One last item: does your code include a reset or init pulse to start the state machine in the IDLE state? If the FPGA powers up with a steady and unending stream of incoming characters on the rx input, will your state machine behave in a consistent and functional manner? Good luck with this exercise. This UART design will hopefully teach you a great deal. -- Bob Elkind SIGNATURE: README for newbies is here: http://forums.xilinx.com/t5/New-Users-Forum/README-first-Help-for-new-users/td-p/219369 Summary: 1. Read the manual or user guide. Have you read the manual? Can you find the manual? 2. Search the forums (and search the web) for similar topics. 3. Do not post the same question on multiple forums. 4. Do not post a new topic or question on someone else's thread, start a new thread! 5. Students: Copying code is not the same as learning to design. 6 "It does not work" is not a question which can be answered. Provide useful details (with webpage, datasheet links, please). 7. You are not charged extra fees for comments in your code. 8. I am not paid for forum posts. If I write a good post, then I have been good for nothing. |
|
|
|
你在这里有很多好的建议。
“这意味着过度采样接收器输入(比如16倍)” 16是过采样的一个非常常用的值,因为它很容易实现 在中等规模的综合逻辑中(早在TTL时代)。 在FPGA中没有任何东西 大约16岁的魔法。你自己制作一个柜台,所以它可以是任何东西。 我有一个UART 设计使用输入时钟作为采样率,所以在你的情况下 过采样868次。 当您的广告费率接近输入时钟频率时, 使用16等大的固定值进行过采样会导致很多错误 比特率计数器。 在您的情况下,您的时钟波特率是868,这是可以考虑的因素 例如,选择这些因子的子集通常很方便.2 * 2 * 7 * 31 在这种情况下,31作为过采样率,其余因素作为时钟 除数产生采样率,在这种情况下为2 * 2 * 7或28.或者你可以 很容易将时钟除以62,过采样为14,依此类推。 强大的UART通常会有一些错误报告信号,用于检查帧错误 通过检测到预期时未检测到停止位,以及奇偶校验时的奇偶校验错误 启用。 此外,根据与其他逻辑的接口,它可能会检测到溢出错误 当内部逻辑错过接收到的字符时,它会尝试传输太快或欠载。 当线路保持低电平时,您还可以检测到“中断”条件 当线路脉冲低得多时,字速率和潜在的波特率不匹配 超过一个比特周期(但超过输入过滤周期)。 当采样速度非常快时 最好使用去毛刺滤波器。 在16倍过采样或更低的情况下,您可能不需要 去除毛刺,除非你以非常高的波特率运行。 你需要问问自己是否在抽样 比输入信号的上升和下降时间快,如果是,则使用去毛刺。 在研究一个新的(对我来说)界面设计时,我通常会开始查看维基百科。 除了Wiki页面本身之外,它经常指向许多有用的信息。 还有一些东西 通常由FPGA初学者设计为UART,您可以查看fpga4fun.com。 - Gabor 以上来自于谷歌翻译 以下为原文 You got a lot of good tips here. "this means oversampling the receiver input (say by a factor of 16)" 16 is a very commonly used value for oversampling as it was easily implemented in medium-scale integrated logic (back in the TTL days). In an FPGA there's nothing magic about 16. You make the counter yourself, so it can be anything. I have a UART design that uses the input clock as the sampling rate, so in your case that would be 868 times oversampling. When your boud rate gets close to the input clock rate, using a large fixed value like 16 for oversampling can cause a lot of error in the bit rate counter. In your case your clock to baud ratio is 868 which can be factored into 2 * 2 * 7 * 31. It's often convenient to pick a subset of these factors, for example 31 in this case, as the oversampling rate, and the remaining factors as the clock divisor to generate the sampling rate, 2 * 2 * 7 in this case or 28. Or you could ust as easily divide the clock by 62 to oversample by 14 and so on. A robust UART usually has some error reporting signals that check for framing errors by detecting that a stop bit was not detected when expected, and parity errors when parity is enabled. Also depending on the interface to other logic it may detect overrun errors when the internal logic tries to transmit too fast or underrun when it misses received characters. You could also detect "break" conditions when the line is held low for some multiple of the word rate, and potential baud mis-match when the line pulses low significantly less than one bit period (but more than the input filter period). When sampling very fast it's a good idea to use a de-glitch filter. At 16x oversampling or less you probably don't need de-glitching unless you run at very high baud rates. You need to ask yourself if you are sampling faster than the rise and fall time of the input signal, and if so use de-glitching. I would usually start looking on Wikipedia when looking into a new (to me) interface design. It often points to a lot of useful information in addition to the Wiki page itself. Also for something as commonly designed by FPGA beginners as a UART, you could look at fpga4fun.com. -- Gabor |
|
|
|
ftwilliam写道:
感谢Bob提供的所有技巧。我需要更好地了解异步串行接口的工作原理; 我将查看其他实现以供参考。我当然认为我将从这个练习中学到很多东西:-) 你会。 这是一个常见的问题,但它值得做,因为有微妙的工作要做。 举个例子,假设你的全局时钟是100 MHz,那你就是115200 bps。 正如我们所见,每位有868个时钟。 我喜欢做的是查找起始位的第一个下降沿,然后将波特率计数器重置为434或半个小时。 当计数器翻转时,检查我们是否仍然有一个低(有效的起始位),然后将计数器预置为868.当计数器翻转时捕获每个数据位。 还要检查有效的停止位。 (除了计数器和数据移位寄存器之外,你还需要一个小的状态机。你可能也希望包括断点检测和线路丢失状态)通过这样做,你重新同步到每个进入的字节 。 ----------------------------是的,我这样做是为了谋生。 以上来自于谷歌翻译 以下为原文 ftwilliam wrote:You will. it's a common problem but it's worth doing because there are subtleties to work through. Just as an example, say your global clock is 100 MHz and you're doing 115200 bps. As we've seen there are 868 clocks per bit. What I like to do is to look for that first falling edge of the start bit and then reset the baud-rate counter to 434, or half a bit time. When the counter rolls over, check to see if we still have a low (valid start bit), then preset the counter to 868. capture each data bit when the counter rolls over. Also check for a valid stop bit. (you need a little state machine in addition to the counter and the data shift register. you may want to include break detection and loss-of-line status, too) By doing it this way, you re-synchronize to every byte coming in. ----------------------------Yes, I do this for a living. |
|
|
|
Bassman几乎描述了我的UART采用输入时钟速率采样的方式。
需要注意的一点是,当您运行全双工时(同时发送和接收) 你需要两个比特率计数器,一个是自由运行的,另一个是复位的 在起始位的前沿用于接收。 在传统的UART中运行16倍波特率 时钟(或时钟使能)你还需要两个计数器,但它们只有4位长。 - Gabor 以上来自于谷歌翻译 以下为原文 Bassman describes pretty much the way my UART works with the sampling at the input clock rate. One thing to note is that when you are running full duplex (transmitting and receiving at the same time) you need two bit rate counters, one free-running for transmitting, and one that gets reset on the front edge of the start bit for receiving. In the traditional UART that runs on a 16x baud clock (or clock enable) you would also need two counters, but they'd only be 4 bits long. -- Gabor |
|
|
|
None
以上来自于谷歌翻译 以下为原文 Thank you guys for all the inputs :-) I came up with a very robbust uart receiver; I get no receiption errors regardless of whether I use a debouncer on the "rx" input to remove noise :-) I especially thank Avrum on its tips on sampling past the start of each bits, and tips from all of you guys on synchronizing the receiver every bits :-) To respond to Bob, I have no reset input or error reporting output to keep it very simple; the receiver and transmitter will settle to a known state after a known number of clock cycles that I have commented on how to calculate. Below you will see the full source code for the receiver and transmitter; It is well commented on how to set the "clock cycle per bit" macro based on your clock speed and the bitrate(baudrate) that you want. I hope it helps someone else :-) UART RECEIVER // Module implementing a uart receiver.// The following implementation// follow rs232 standard signalling// with the following properties:// // - Expect to receive 8 data bits;// no parity bits.// - Receive least significant bit first.// - Expect to receive at least 1 stop bit;// will not check or fail if there is// more than 1 stop bit.// // An 8 bits data transmission begin// with a start bit which is a logic low// state of the data line, followed by// the 8 bits to transmit and terminated// by 1 or more stop bits which are logic// high states of the data line.// The following macros// definition must fall-through// when inserting this file.// // CLOCKCYCLESPERBIT:// This macro define the number// of clock cycles per bit.// Given the bitrate and clock// speed, it is calculated using// the following formula:// ((clockspeed/bitrate) + ((clockspeed/bitrate)/10/2));// where the expression ((clockspeed/bitrate)/10/2)// is the clock cycles amount that insure// that the receiver will sample past// the start of each bit.// Note that, as the receiver go through// its idle state to start receiving// the next byte, any accumulated// skew from the beginning of a bit// get discarded as the receiver// detect the exact beginning of a bit.// ei: For a clockspeed of 100Mhz// and a bitrate of 115200, the// above formula would yield 910.458;// the value of this macro is then// picked as: 910 or 911.// The value of this macro// should never be 0. ei:// `define CLOCKCYCLESPERBIT 911// // To change the name of the module,// a macro having the name of the module,// all lowercase, should fall-through// when inserting this file; the value// of the macro will be used as the name// of the module.// Description of the ports.// // input clk// Clock signal.// // input rx// Incoming serial line.// // output received// This signal become high// to indicate that a byte// has been received.// This signal is high// for one clock cycle.// // output[8] data// Byte value received.// Its value is valid only while// the output "received" is high.// // To skip unknown states on// the output "received", after// poweron this module must be run// for a clock cycle count of at least// (10 * $CLOCKCYCLESPERBIT), with// the input "rx" set high; unknown// states get flushed out of the module.module uartreceiver(input clk,input rx,output reg received,output reg[8 -1 : 0] data);// Note that there is no// output signal reporting// whether the module is// receiving, because// reception activities// can be assumed occuring// if the input "rx" is// changing state.parameter CLOCKCYCLESPERBIT = 911;parameter LOG2CLOCKCYCLESPERBIT = 10;// Values used with// the register rxstate.// Receiver is waiting// on a transmission.parameter RXIDLE = 0;// Receiver is receiving bits.parameter RXRECEIVE = 1;// Receiver is checking for// the end of a transmission.parameter RXSTOP = 2;// Register which hold// the state of the receiver.reg[2 -1 : 0] rxstate;// Register that will be used to keep// a count of the number of clock cycles.reg[LOG2CLOCKCYCLESPERBIT -1 : 0] counter;// Register which is used// to keep track of the number// of bits left to receive.reg[3 -1 : 0] bitcount;always @(posedge clk) begin// Logic updating the// register counter.if (rxstate == RXIDLE || counter == (CLOCKCYCLESPERBIT -1)) counter <= 0;else counter <= counter + 1'b1;// Enable clocking of registers// only for every bit.if (counter == (CLOCKCYCLESPERBIT -1) && rxstate == RXRECEIVE) begin// At the last bit to receive,// "bitcount" will be 0, and// will be automatically reset// to 7 when decremented.bitcount <= bitcount - 1'b1;// Logic that store each bit.data <= {rx, data[7:1]};endif (rxstate == RXIDLE) begin// I get here if the receiver// is in an idle state.// I check for the start// of a transmission.// A change of the incoming// serial line state to low// indicate the start of// a transmission.if (!rx) rxstate <= RXRECEIVE;received <= 0;// Enable clocking of registers// only for every bit.end else if (counter == (CLOCKCYCLESPERBIT -1)) beginif (rxstate == RXSTOP) begin// If I get here,// I expect a stop bit// which correspond to// the incoming serial// line being high.if (rx) received <= 1;// I set the receiver state// to iddle so as to wait// for the next transmission.rxstate <= RXIDLE;end else begin// At the last bit to receive,// I set the receiver state// so as to expect a stop bit.if (!bitcount) rxstate <= RXSTOP;endendendendmodule UART TRANSMITTER // Module implementing a uart transmitter.// The following implementation// follow RS232 standard signalling// with the following properties:// // - Expect to send 8 data bits;// no parity bits.// - Send least significant bit first.// - Transmit 2 stop bits.// // An 8 bits data transmission begin// with a start bit which is a logic low// state of the data line, followed by// the 8 bits to transmit and terminated// by 1 or more stop bits which are logic// high states of the data line.// The following macros// definition must fall-through// when inserting this file.// // CLOCKCYCLESPERBIT:// This macro define the number// of clock cycles per bit.// Given the bitrate and clock// speed, it is calculated using// the following formula:// (clockspeed/bitrate);// The result of the above formula// should be rounded-down, because// it is better to have a slightly// lower estimation of the duration// of a bit, this way a receiver// is guarantied to always sample// past the beginning of each bit,// and not fall short by sampling// the same bit twice.// ei: For a clockspeed of 100Mhz// and a bitrate of 115200, the// above formula would yield 867.056;// the value of this macro is then// picked as: 867.// The value of this macro// should never be 0. ei:// `define CLOCKCYCLESPERBIT 867// // To change the name of the module,// a macro having the name of the module,// all lowercase, should fall-through// when inserting this file; the value// of the macro will be used as the name// of the module.// Description of the ports.// // input clk// Clock signal.// // output tx// Outgoing serial line.// // input transmit// This signal is set high to// start trasmitting the byte// value on the input "data".// It must be kept high until// a negative edge on the output// "dataneeded" occur, which// mean that the byte value on// the input "data" has been// captured for transmission.// This signal can be continuously// held high to keep transmitting// the byte value on the input// "data"; the next value to transmit// must be set on the input "data"// as soon as the output "dataneeded"// become high; in fact the output// "dataneeded" will remain high// for a clock cycle count of at// least (2 * $CLOCKCYCLESPERBIT).// // input[8] data// Byte value to transmit// through the output "tx".// The byte value is captured// for transmission when the input// "transmit" is high and the output// "dataneeded" is high; hence the// next value to transmit must be set// as soon as the output "dataneeded"// become high; in fact the output// "dataneeded" will remain high// for a clock cycle count of at// least (2 * $CLOCKCYCLESPERBIT).// // output dataneeded// When this signal become high,// the byte value to transmit// must be set on the input "data".// This signal remain high for// a clock cycle count of at// least (2 * $CLOCKCYCLESPERBIT).// // To skip unknown states on// the output "tx", after poweron// this module must be run for// a clock cycle count of at least// (10 * $CLOCKCYCLESPERBIT), with// the input "transmit" set low;// unknown states get flushed out// of the module.module uarttransmitter(input wire clk,output reg tx,input wire transmit,input wire[8 -1 : 0] data,output wire dataneeded);// Note that there is no// output signal reporting// whether the module is// transmitting, because// transmission activities// can be assumed occuring// if the output "tx" is// changing state.parameter CLOCKCYCLESPERBIT = 867;parameter LOG2CLOCKCYCLESPERBIT = 10;// Values used with// the register txstate.// Transmitter is either// sending stop bits, or// waiting for the input// "transmit" to become high// to begin transmitting the// byte on the input data.parameter TXIDLE = 0;// Transmitter is// sending data bits.parameter TXSEND = 1;// Register which hold the// state of the transmitter.reg txstate;assign dataneeded = (txstate == TXIDLE);// Register that will be used to keep// a count of the number of clock cycles.reg[LOG2CLOCKCYCLESPERBIT -1 : 0] counter;// Register which will hold// the bits to transmit,// clocked in from// the input "data".reg[8 -1 : 0] bitstotransmit;// Register which is used// to keep track of the number// of bit left to send.reg[3 -1 : 0] bitcount;always @(posedge clk) begin// Enable clocking of registers// only for every bit.if (counter == (CLOCKCYCLESPERBIT -1)) beginif (txstate == TXIDLE) begin// The transmitter remain// in this state until the// input signal "transmit"// become high to begin// transmitting.// If bitcount is true,// I send stop bits for// the amount in bitcount.if (bitcount) beginbitcount <= bitcount - 1'b1;tx <= 1;end else if (transmit) begintxstate <= TXSEND;bitstotransmit <= data;// I send start bit.tx <= 0;bitcount <= 7;endend else begin// I transmit bitstotransmit[0].tx <= bitstotransmit[0];if (bitcount) beginbitcount <= bitcount - 1'b1;// I select the next// bit to transmit.bitstotransmit <= bitstotransmit >> 1'b1;end else begintxstate <= TXIDLE;// I set bitcount// to 2 in order to// send 2 stop bits.bitcount <= 2;endendcounter <= 0;end else counter <= counter + 1'b1;endendmodule |
|
|
|
只有小组成员才能发言,加入小组>>
2416 浏览 7 评论
2821 浏览 4 评论
Spartan 3-AN时钟和VHDL让ISE合成时出现错误该怎么办?
2292 浏览 9 评论
3372 浏览 0 评论
如何在RTL或xilinx spartan fpga的约束文件中插入1.56ns延迟缓冲区?
2458 浏览 15 评论
有输入,但是LVDS_25的FPGA内部接收不到数据,为什么?
1124浏览 1评论
请问vc707的电源线是如何连接的,我这边可能出现了缺失元件的情况导致无法供电
581浏览 1评论
求一块XILINX开发板KC705,VC707,KC105和KCU1500
447浏览 1评论
2002浏览 0评论
725浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 00:37 , Processed in 1.537332 second(s), Total 89, Slave 72 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号