EmbDev.net

Forum: FPGA, VHDL & Verilog help with uart


von PEter (petah)


Attached files:

Rate this post
useful
not useful
Hello,

I am trying to send some data via UART. I have a shift register which 
stores a value for 24 clk cycles. Meanwhile I want this value to be sent 
via UART because after that the register will have another value saved 
into it. Is this even possible? In a picture that I have added it's my 
simulation. You can see that the value "15" is stored in SR for 24 
cycles. How do I send it via UART? Thanks for any help in advance!

1
 
2
3
`timescale 1ns / 1ps
4
 
5
module flipflop(
6
    input wire D_1, //vhod prvi ff
7
    input wire f_clk, //clock
8
    input wire rst, //reset
9
    input wire en, //enable
10
    output reg O //izhod AND vrat
11
);
12
parameter N = 24;
13
reg [N-1:0] SR = 0, SR_next = 0; //shift register
14
reg [1:0] SR_2 = 2'b11; //drugi shift register
15
reg SR_set = 1, SR_en;
16
reg [N-1:0] Q_4; //shift register izhod
17
reg Q_1;
18
reg Q_2;
19
reg Q_3;
20
reg Q_3_neg; //negirana vrednost izhoda detektorja
21
reg [15:0] counter = 0;
22
reg [15:0] counter_reg = 0;
23
reg [4:0] shift_counter = 0;
24
reg [16:0] counter8ciklov = 0;
25
26
    always @(posedge f_clk or posedge rst) begin
27
        if (rst) begin
28
            Q_1 <= 0;
29
        end
30
        else if (en) begin
31
            Q_1 <= D_1;
32
        end
33
    end
34
    
35
    
36
    
37
        
38
    always @(posedge f_clk or posedge rst) begin
39
        if (rst) begin
40
            Q_2 <= 0;
41
            counter <=0;
42
            counter_reg <=0;
43
        end
44
        else if (en) begin
45
            Q_2 <= Q_1;
46
        end
47
    end
48
   
49
   
50
   
51
   always @(posedge f_clk) begin
52
          Q_3 <= Q_2 ; 
53
          Q_3_neg <=~Q_3;
54
          O <= Q_2 & ~Q_3;    
55
    end
56
57
58
59
60
61
always @(posedge f_clk) begin
62
    if (O) begin
63
        counter_reg <= counter;
64
        counter <= 0;
65
    end else begin
66
        counter <= counter + 1;
67
    end
68
end
69
70
71
//shift register 1
72
73
always @(posedge f_clk) begin
74
if ( SR_set )
75
begin
76
SR <= counter_reg;
77
SR_set <= 0;
78
end else begin
79
SR <= SR;
80
end
81
end
82
83
//shift register 2
84
85
86
always @(posedge f_clk)begin
87
if(shift_counter == 4'b0001)begin //DODAJ ŠE && tx_busy !!!!!!!!!!!!
88
SR_en = 1;
89
end
90
if(counter8ciklov == 7)begin
91
SR_en = 0;
92
end
93
end
94
95
always @(SR)begin
96
if(shift_counter == 4'b0000)begin
97
shift_counter <= shift_counter + 4'b0001;
98
end 
99
end
100
101
always @(posedge f_clk)begin
102
if(shift_counter >= 4'b0001 && shift_counter <= 4'b1110)begin
103
shift_counter <= shift_counter+ 4'b0001;
104
end else begin
105
if(shift_counter == 4'b1111)begin
106
shift_counter <= 4'b0000;
107
end
108
end
109
110
end
111
112
always @(posedge f_clk)begin
113
if(SR_2 != 2'b01) begin
114
counter8ciklov <= 0;
115
end
116
if(shift_counter == 4'b1000 || shift_counter == 4'b1111) begin
117
SR_2 <= SR_2 +1;
118
end
119
if(counter8ciklov < 3'b111 && SR_2 == 2'b01)begin
120
counter8ciklov <= counter8ciklov +1;
121
end else begin
122
if(counter8ciklov ==3'b111 && SR_2 == 2'b01)begin
123
SR_2 <= SR_2 +2;
124
counter8ciklov <= 0;
125
end
126
end
127
end
128
129
always @(posedge O && SR_2 == 2'b11)begin
130
SR_set <= 1;
131
end
132
133
endmodule

von Vancouver (vancouver)


Rate this post
useful
not useful
PEter wrote:

> I am trying to send some data via UART. I have a shift register which
> stores a value for 24 clk cycles. Meanwhile I want this value to be sent
> via UART because after that the register will have another value saved
> into it. Is this even possible?

The Shiftregister 15 bits wide. Sending via uart requires two data bytes 
with 1 start and 1 stop bit each (8N1). So you will need to transmit 20 
bits, and you have 24 clock cycles time.
So if the UART transmits with a bit rate ~equal to the clock rate, yes 
then its possible. If the UART is slower, no.

von Antti L. (trioflex)


Rate this post
useful
not useful
PEter wrote:
> Hello,
>
> I am trying to send some data via UART. I have a shift register which

maybe you should look into uart.v in the zip file you attached to your 
post?

There seems to be WORKING UART implementation, so you only need to use 
it, and you are done.

von PEter (petah)


Rate this post
useful
not useful
First I would like to thank you both for answering.
1. Can I set the speed of UART or is this a fixed max value that I have 
to read in the datahseet of artix7 ? Or did you just mean the baud rate 
by this ?
2. I knew it will need 2 transfers of 8 bits for data and all the stop 
and start bits together shouldn't exceed the 24 clock cycles (if the 
UART speed is fast enoguh). So I understand that.
3. I do have a working uart but I don't know how to implement it into my 
project. At UNI we did that UART example but I don't know how to use it 
in my project. I would be grateful if you could have helped me out.

Thank you again for your replys

: Edited by User
von Antti L. (trioflex)


Rate this post
useful
not useful
PEter wrote:

> project. At UNI we did that UART example but I don't know how to use it
> in my project. I would be grateful if you could have helped me out.

you should have started so:

I have homework at the UNI where I need to use UART and I do not know 
how.

Please help me with my homework.

: Edited by User
von PEter (petah)


Rate this post
useful
not useful
I am sorry but this is not a homework. I am trying to build a detector 
which will detect to which way the current is flowing. The only part 
from the UNI is the UART part.

von Antti L. (trioflex)


Rate this post
useful
not useful
PEter wrote:
> I am sorry but this is not a homework. I am trying to build a detector
> which will detect to which way the current is flowing. The only part
> from the UNI is the UART part.

Well then USE the UART.v code, the uart is there just use it.
If you do not know how to use a verilog module then use google.

von PEter (petah)


Rate this post
useful
not useful
As said I do not know how to implement it into my project therefore I am 
trying to find help here.

von Antti L. (trioflex)


Rate this post
useful
not useful
PEter wrote:
> As said I do not know how to implement it into my project therefore I am
> trying to find help here.

And I did tell you to use google. OK I do it for you:

google: how to instatiate verilog modules
I did this for you, and did take FIRST LINK

https://www.chipverify.com/verilog/verilog-module-instantiations

it explains how to use verilog modules. Just instatiate the uart_tx 
module and use it then as needed in your top-level design.

von PEter (petah)


Rate this post
useful
not useful
I tried many things. Now even that from the forum you have sent me. I 
can't figure it out.
1
// Instantiate tx_uart module
2
tx_uart #(.DATA_WIDTH(8), .FREQ(10000000), .BAUD(115200)) uart_tx_inst (
3
    .i_clk(f_clk),
4
    .i_rst(rst),
5
    .i_data(Q_4),  // Data I want to send to UART
6
    .i_valid(SR_en),
7
    .o_tx(),  // Connect to  output (an external pin)
8
    .o_busy(tx_busy)  // Connect to tx_busy 
9
);
10
11
wire tx_output_signal;
12
assign tx_output_signal = uart_tx_inst.o_tx;
13
endmodule

This is the code I added, since I only need to use TX. The problem is 
that I dont really understand what is going on here. Im trying to do a 
simulation but tx_output_signal is low at all times. Also tx_busy is set 
to busy all the time.

von Antti L. (trioflex)


Rate this post
useful
not useful
PEter wrote:
> I tried many things. Now even that from the forum you have sent me. I
> can't figure it out.
>
1
// Instantiate tx_uart module
2
> tx_uart #(.DATA_WIDTH(8), .FREQ(10000000), .BAUD(115200)) uart_tx_inst (
3
>     .i_clk(f_clk),
4
>     .i_rst(rst),
5
>     .i_data(Q_4),  // Data I want to send to UART
6
>     .i_valid(SR_en),
7
>     .o_tx(),  // Connect to  output (an external pin)
8
9
here you should connect tx_output_signal and not use assign!!!!
10
11
>     .o_busy(tx_busy)  // Connect to tx_busy
12
> );
13
> 
14
> wire tx_output_signal;
15
> assign tx_output_signal = uart_tx_inst.o_tx;
16
> endmodule
17
> 
18
>
>
> This is the code I added, since I only need to use TX. The problem is
> that I dont really understand what is going on here. Im trying to do a
> simulation but tx_output_signal is low at all times. Also tx_busy is set
> to busy all the time.

this is some weird way todo things. You should have see above, used the 
output signal in instantion.

how long is your VALID pulse? How long did you simulate? The UART will 
send 0 for START as long as one bit time at the beginning. But BEFORE 
valid going low output should be high for sure, and busy should be low 
after reset before valid

: Edited by User
von Antti L. (trioflex)


Rate this post
useful
not useful
PEter wrote:
> I tried many things. Now even that from the forum you have sent me. I
> can't figure it out.
> [code]// Instantiate tx_uart module
> tx_uart #(.DATA_WIDTH(8), .FREQ(10000000), .BAUD(115200)) uart_tx_inst (
>     .i_clk(f_clk),
>     .i_rst(rst),
>     .i_data(Q_4),  // Data I want to send to UART
>     .i_valid(SR_en),
>     .o_tx(),  // Connect to  output (an external pin)
>     .o_busy(tx_busy)  // Connect to tx_busy
> );
>

it seems your uart_tx has major issue in the code, namely the START bit 
can be random length depending when you assert valid. But that is not 
yet your problem, you have some more issues to solve out.
also it seems busy is never cleared.. but it should be low after reset 
until valid comes, then when it asserts it is asserted forever.

maybe get some better UART IP core, that works

: Edited by User
von PEter (petah)


Rate this post
useful
not useful
here you should connect tx_output_signal and not use assign!!!!
I dont know what you mean. I know that o.tx() is the serial data that 
will be transmitted. I just made tx_output_signal to try to simulate it 
but it didnt work.

I am running simulation for 1000ns. Data_valid  should be positive when 
SR_en = 1 right ? .i_valid(SR_en)

In that case, SR_en is on for 40ns so the i_valid should be the same

I just want the variables from my module that I crated to be used in the 
module UART

I have SR (its counting clk cycles from ADC)  which I need to be sent 
via UART. This data can be sent while SR_en = 1 and meanwhile i need 
tx_busy to be 1. I dont know how to do that.

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.