Forum Discussion
Altera_Forum
Honored Contributor
12 years agoUART and MODELSIM ALTERA (code attached)
Hi dears.
I am trying to use a (slightly) modified version of the UART explained in a tutorial I've found, after reading some theory about. There is one UART entity which has two components - TX and RX, which in turn, operate with 9600bps in transmition and reception of bytes. The UART has two serial ports and two "parallel" ports for doing serial<->parallel conversion. The simulation results (for RX) can be visualized here: http://puu.sh/6tnpq/db6251b4ec.png My doubt: I am writing one byte 11111111 in the parallel_tx sign and I expect it to be passed to UART_RXD (not occurring in simulation). All the right sided signals are included in the sensitive list of all process as taught me here (the original code had not). I can't see any syntax erro on the codes (I had not noted any appointment in the comments where I took it from (Toni Axe, youtube)). note: I see that the RX and TX codes are written just with one process, with IFs operating as states (not using switch as I usually do). Any help will be appreciated (I created this post after 3 days trying to do it "by my self" in my DE2). thanks. PS: I am using 20000 ps clock period.29 Replies
- Altera_Forum
Honored Contributor
Thank Tricky, I will try it but, as soon as I am modeling the uart through Flip-Flops,
and using two signals to do in this way, I am thinking witch is the best practice to implement it. As a beginner Is it suggested to do it in the sequential logic process......or in the combinational part, outside the process? sequential logic process: entity ... port( rx: in std_logic ); ... archtecture ... -- two signals representing the Next State Logic register for a byte comming in port rx. signal b_reg, b_next: std_logic_vector(7 downto 0); -- other two signals representing the other register signal other_b_reg, other_b_next: std_logic_vector(7 downto 0); ... process(clk, reset) ... -- next state logic for b and... b_reg <= b_next; -- ...the other register. other_b_next <= b_reg;other_b_reg <= other_b_next; combinational logic: ... process(clk,rst) ... end process; ... process(sensitivity list) .... end process; ... --outside the process. b_reg <= b_next; other_b_next <= b_reg;
other_b_reg <= other_b_next; or even do i need another case statment in the finite state machine process just to pass the value from one signal to the other? It seems that we have a hot topic here (Views: >1,218). Thanks,
- Altera_Forum
Honored Contributor
just register them directly:
Then use rd_r(1) instead of the origional input "rd" and the same for serial_rxsignal rd_r : std_logic_vector(1 downto 0); signal serial_rx_r : std_logic_vector(1 downto 0); process(clk) begin if rising_edge(clk) then serial_rx_r <= serial_rx_r(0) & serial_rx; rd_r <= rd_r(0) & rd; end if; end if; - Altera_Forum
Honored Contributor
--- Quote Start --- just register them directly:
Then use rd_r(1) instead of the origional input "rd" and the same for serial_rx --- Quote End --- Hi tricky, I am doing this already, for example, in the line 110 from the rx_uart.vhd:signal rd_r : std_logic_vector(1 downto 0); signal serial_rx_r : std_logic_vector(1 downto 0); process(clk) begin if rising_edge(clk) then serial_rx_r <= serial_rx_r(0) & serial_rx; rd_r <= rd_r(0) & rd; end if; end if;
Maybe the problem is with the FIFO megafunction? I am using the SCFIFO from altera. So, the input "rd" from this SCFIFO is connected with the output "rx_done_tick" from rx_uart.vhd. Maybe I should use the DCFIFO, which I read that it is better for deal with metastability. I noted too that the counter from mod_27.vhdl does not flash the leds to indicate that the counter inside is working. The outputs in this vhdl file are in this way:-- left concatenate the new bit, assuming the bits are sent LSB to MSB byte_next <= rx & byte_reg(7 downto 1);
I think it should be corrected as you said. I'll try to double register these two outputs and test the counter first. Then I ll increment the circuitry with uart, then with the FIFO, and see if it works.-- output logic q <= std_logic_vector(r_reg); max_tick <= '1' when r_reg=(M-1) else '0'; - Altera_Forum
Honored Contributor
--- Quote Start --- Hi tricky, I am doing this already, for example, in the line 110 from the rx_uart.vhd:
--- Quote End --- THis assumes that the rx input is already synchronised which it isnt. You need the double register BEFORE this to ensure you get real values, not a meta stable one inside the byte(0) register. The problem will not be the DCFIFO. THat also requires synchronised inputs.-- left concatenate the new bit, assuming the bits are sent LSB to MSB byte_next <= rx & byte_reg(7 downto 1); - Altera_Forum
Honored Contributor
--- Quote Start --- just register them directly:
Then use rd_r(1) instead of the origional input "rd" and the same for serial_rx --- Quote End --- I know it is a lot of questions but: I noted that you coded inside the reset process. I am doing this "shifting register" in another process where I've implemented the FSM. I have a process for clock and reset, and another process for FSM. Should I implement the double register in the clock/reset process? Not in the FSM process? This is causing to me some confusion.signal rd_r : std_logic_vector(1 downto 0); signal serial_rx_r : std_logic_vector(1 downto 0); process(clk) begin if rising_edge(clk) then serial_rx_r <= serial_rx_r(0) & serial_rx; rd_r <= rd_r(0) & rd; end if; end if; - Altera_Forum
Honored Contributor
Yes, it is. You have separated out all of your combinatorial logic into one process, and then registered it in another.
Aslong as they are placed in a clocked process that uses the correct clock, then its fine. - Altera_Forum
Honored Contributor
--- Quote Start --- Yes, it is. You have separated out all of your combinatorial logic into one process, and then registered it in another. Aslong as they are placed in a clocked process that uses the correct clock, then its fine. --- Quote End ----- register byte_reg syncronized; process(clk, reset) begin if (reset = '1') then state_reg <= idle; baud_cnt_reg <= (others => '0'); bits_cnt_reg <= (others => '0'); byte_reg <= (others => '0'); elsif (clk'event and clk='1') then state_reg <= state_next; baud_cnt_reg <= baud_cnt_next; bits_cnt_reg <= bits_cnt_next; byte_reg <= byte_next; end if; end process; ... -- left concatenate the new bit, assuming the bits are sent LSB to MSB -- other process (FSM). byte_next <= rx & byte_reg(7 downto 1); ... -- out of any process, combinatorial logic. -- Put the byte read on the output bus. dout <= byte_reg; - Altera_Forum
Honored Contributor
IT WORKED! I LOVE YOU TRICKY :D \o/
- Altera_Forum
Honored Contributor
--- Quote Start --- IT WORKED! I LOVE YOU TRICKY :D \o/ --- Quote End --- hi friend, i need uart_rx , uart_tx , uart_testbench ; code for modelsim can you send it for me as soon AS possible? my mail: [email protected] thanks alot