├── simulation └── rtl_sims │ ├── simulation.tcl │ ├── rtl_sim.f │ ├── modelsim_rtl_sim.f │ └── isim_rtl_sim.f ├── rtl ├── uart_echo.f ├── uart_echo.v ├── uart_fifo.v ├── fifo.v └── uart.v ├── README.md ├── testbench ├── dump.v └── testbench.v ├── configurations ├── simulate_modelsim.json ├── simulate_iverilog.json ├── simulate_isim.json └── simulate_ncverilog.json ├── behavioral ├── behavioral.f ├── wb_master │ ├── wb_model_defines.v │ └── wb_mast_model.v └── wb_uart │ ├── timescale.v │ ├── uart_sync_flops.v │ ├── raminfr.v │ ├── uart_debug_if.v │ ├── uart_tfifo.v │ ├── uart_defines.v │ ├── uart_rfifo.v │ ├── uart_wb.v │ ├── uart_top.v │ ├── uart_transmitter.v │ └── uart_receiver.v ├── fpga └── xilinx │ └── basys3 │ ├── basys3.xdc │ └── basys3.xpr ├── .gitignore ├── LICENSE ├── tasks ├── includes.v └── uart_tasks.v └── tools └── run_sim.py /simulation/rtl_sims/simulation.tcl: -------------------------------------------------------------------------------- 1 | run all 2 | -------------------------------------------------------------------------------- /rtl/uart_echo.f: -------------------------------------------------------------------------------- 1 | ../../rtl/uart.v 2 | ../../rtl/uart_echo.v 3 | ../../rtl/uart_fifo.v 4 | ../../rtl/fifo.v 5 | -------------------------------------------------------------------------------- /simulation/rtl_sims/rtl_sim.f: -------------------------------------------------------------------------------- 1 | +libext+.v+.V+.ver 2 | +incdir+../../tasks/ 3 | 4 | ../../tasks/uart_tasks.v 5 | ../../testbench/testbench.v 6 | ../../testbench/dump.v 7 | 8 | -f ../../behavioral/behavioral.f 9 | -f ../../rtl/uart_echo.f 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UART_ECHO 2 | Verilog UART FIFO that will just echo back characters. Useful for testing the communications path. 3 | 4 | The UART itself was taken from http://opencores.org/project,osdvu. This UART is licensed under the MIT license just like this project is. 5 | -------------------------------------------------------------------------------- /testbench/dump.v: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | module dump; 5 | 6 | initial 7 | begin 8 | `ifdef NCVERILOG 9 | $shm_open("test.shm"); 10 | $shm_probe(testbench, "MAC"); 11 | `else 12 | $dumpfile("dump.vcd"); 13 | $dumpvars(0, testbench); 14 | `endif 15 | 16 | end // initial begin 17 | 18 | 19 | endmodule // test_top 20 | -------------------------------------------------------------------------------- /configurations/simulate_modelsim.json: -------------------------------------------------------------------------------- 1 | { 2 | "project":"simulate_modelsim", 3 | "installed tools": [ 4 | "xilinx", 5 | "altera", 6 | "icarus" 7 | ], 8 | "flow_steps": { 9 | "1" : "simulation" 10 | }, 11 | "flow" : { 12 | "simulation" : { 13 | "executable": "vsim", 14 | "arguments" : " -c -do modelsim_rtl_sim.f -l modelsim_logfile.txt" 15 | }, 16 | "run" : { 17 | "executable" : "./a.out", 18 | "arguments" : " " 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /behavioral/behavioral.f: -------------------------------------------------------------------------------- 1 | +incdir+../../behavioral/wb_master/ 2 | ../../behavioral/wb_master/wb_mast_model.v 3 | 4 | 5 | +incdir+../../behavioral/wb_uart/ 6 | ../../behavioral/wb_uart/raminfr.v 7 | ../../behavioral/wb_uart/uart_debug_if.v 8 | ../../behavioral/wb_uart/uart_receiver.v 9 | ../../behavioral/wb_uart/uart_regs.v 10 | ../../behavioral/wb_uart/uart_rfifo.v 11 | ../../behavioral/wb_uart/uart_sync_flops.v 12 | ../../behavioral/wb_uart/uart_tfifo.v 13 | ../../behavioral/wb_uart/uart_top.v 14 | ../../behavioral/wb_uart/uart_transmitter.v 15 | ../../behavioral/wb_uart/uart_wb.v 16 | -------------------------------------------------------------------------------- /configurations/simulate_iverilog.json: -------------------------------------------------------------------------------- 1 | { 2 | "project":"simulate_iverilog", 3 | "installed tools": [ 4 | "xilinx", 5 | "altera", 6 | "icarus" 7 | ], 8 | "flow_steps": { 9 | "1" : "clean_up", 10 | "2" : "simulation", 11 | "3" : "run" 12 | }, 13 | "flow" : { 14 | "clean_up" : { 15 | "executable" : "rm", 16 | "arguments" : "-f dump.vcd a.out" 17 | }, 18 | "simulation" : { 19 | "executable": "iverilog", 20 | "arguments" : " -f rtl_sim.f" 21 | }, 22 | "run" : { 23 | "executable" : "./a.out", 24 | "arguments" : " " 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /configurations/simulate_isim.json: -------------------------------------------------------------------------------- 1 | { 2 | "project":"simulate_isim", 3 | "installed tools": [ 4 | "xilinx", 5 | "altera", 6 | "icarus" 7 | ], 8 | "flow_steps": { 9 | "1" : "clean", 10 | "2" : "build", 11 | "3" : "simulation" 12 | }, 13 | "flow" : { 14 | "clean" :{ 15 | "executable" : "rm", 16 | "arguments" : "-f dump.vcd fuse.log fuse.xmsgs fuseRelaunch.cmd isim isim.log isim.wdb simulation.exe " 17 | }, 18 | "build" :{ 19 | "executable" : "fuse", 20 | "arguments" : "work.glbl work.testbench -L unisims_ver -L unimacro_ver -L xilinxcorelib_ver -prj isim_rtl_sim.f -o simulation.exe" 21 | }, 22 | "simulation" : { 23 | "executable": "simulation.exe", 24 | "arguments" : "-tclbatch simulation.tcl" 25 | }, 26 | "run" : { 27 | "executable" : "./a.out", 28 | "arguments" : " " 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /configurations/simulate_ncverilog.json: -------------------------------------------------------------------------------- 1 | { 2 | "project":"simulate_iverilog", 3 | "installed tools": [ 4 | "xilinx", 5 | "altera", 6 | "icarus" 7 | ], 8 | "flow_steps": { 9 | "1" : "clean_up", 10 | "2" : "prepare", 11 | "3" : "simulation" 12 | }, 13 | "flow" : { 14 | "clean_up" : { 15 | "executable" : "rm", 16 | "arguments" : "-f dump.vcd a.out" 17 | }, 18 | "prepare" : { 19 | "executable" : "touch", 20 | "arguments" : "cds.lib" 21 | }, 22 | "simulation" : { 23 | "executable": "ncverilog", 24 | "arguments" : " -v93 +access+rwc -clean -cdslib cds.lib -f rtl_sim.f -timescale 1ns/1ns" 25 | }, 26 | "run" : { 27 | "executable" : "./a.out", 28 | "arguments" : " " 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /fpga/xilinx/basys3/basys3.xdc: -------------------------------------------------------------------------------- 1 | ## This file is a general .xdc for the Basys3 rev B board 2 | ## To use it in a project: 3 | ## - uncomment the lines corresponding to used pins 4 | ## - rename the used ports (in each line, after get_ports) according to the top level signal names in the project 5 | 6 | ## Clock signal 7 | set_property PACKAGE_PIN W5 [get_ports CLK] 8 | set_property IOSTANDARD LVCMOS33 [get_ports CLK] 9 | create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports CLK] 10 | 11 | ##Buttons 12 | set_property PACKAGE_PIN U18 [get_ports RESET] 13 | set_property IOSTANDARD LVCMOS33 [get_ports RESET] 14 | 15 | 16 | ##USB-RS232 Interface 17 | set_property PACKAGE_PIN B18 [get_ports RX] 18 | set_property IOSTANDARD LVCMOS33 [get_ports RX] 19 | 20 | set_property PACKAGE_PIN A18 [get_ports TX] 21 | set_property IOSTANDARD LVCMOS33 [get_ports TX] 22 | 23 | 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | 53 | # Sphinx documentation 54 | docs/_build/ 55 | 56 | # PyBuilder 57 | target/ 58 | 59 | # Verilog 60 | a.out 61 | *.vcd 62 | cds.lib 63 | *.exe 64 | *wdb 65 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Phil Tracton 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /simulation/rtl_sims/modelsim_rtl_sim.f: -------------------------------------------------------------------------------- 1 | vlib work 2 | 3 | vlog ../../tasks/uart_tasks.v +incdir+../../tasks/ 4 | vlog ../../testbench/testbench.v +incdir+../../tasks/ 5 | vlog ../../testbench/dump.v 6 | 7 | vlog ../../behavioral/wb_uart/raminfr.v +incdir+../../behavioral/wb_uart/ 8 | vlog ../../behavioral/wb_uart/uart_debug_if.v +incdir+../../behavioral/wb_uart/ 9 | vlog ../../behavioral/wb_uart/uart_receiver.v +incdir+../../behavioral/wb_uart/ 10 | vlog ../../behavioral/wb_uart/uart_regs.v +incdir+../../behavioral/wb_uart/ 11 | vlog ../../behavioral/wb_uart/uart_rfifo.v +incdir+../../behavioral/wb_uart/ 12 | vlog ../../behavioral/wb_uart/uart_sync_flops.v +incdir+../../behavioral/wb_uart/ 13 | vlog ../../behavioral/wb_uart/uart_tfifo.v +incdir+../../behavioral/wb_uart/ 14 | vlog ../../behavioral/wb_uart/uart_top.v +incdir+../../behavioral/wb_uart/ 15 | vlog ../../behavioral/wb_uart/uart_transmitter.v +incdir+../../behavioral/wb_uart/ 16 | vlog ../../behavioral/wb_uart/uart_wb.v +incdir+../../behavioral/wb_uart/ 17 | 18 | vlog ../../behavioral/wb_master/wb_mast_model.v +incdir+../../behavioral/wb_master/ 19 | 20 | 21 | vlog ../../rtl/uart.v 22 | vlog ../../rtl/uart_echo.v 23 | vlog ../../rtl/uart_fifo.v 24 | vlog ../../rtl/fifo.v 25 | 26 | vsim -voptargs=+acc work.testbench +define+ALTERA 27 | run -all 28 | -------------------------------------------------------------------------------- /tasks/includes.v: -------------------------------------------------------------------------------- 1 | // -*- Mode: Verilog -*- 2 | // Filename : includes.v 3 | // Description : include file for the defines 4 | // Author : Philip Tracton 5 | // Created On : Tue Apr 21 18:01:11 2015 6 | // Last Modified By: Philip Tracton 7 | // Last Modified On: Tue Apr 21 18:01:11 2015 8 | // Update Count : 0 9 | // Status : Unknown, Use with caution! 10 | 11 | `define testbench testbench 12 | `define test_failed `testbench.test_failed 13 | `define UART_MASTER0 `testbench.uart_master0 14 | `define UART_MASTER1 `testbench.uart_master1 15 | `define UART_CLK `testbench.clk_tb 16 | `define UART_CONFIG uart_tasks.uart_config 17 | `define UART_WRITE_CHAR uart_tasks.uart_write_char 18 | `define UART_READ_CHAR uart_tasks.uart_read_char 19 | 20 | // general defines 21 | `define mS *1000000 22 | `define nS *1 23 | `define uS *1000 24 | `define Wait # 25 | `define wait # 26 | `define khz *1000 27 | 28 | 29 | 30 | // Taken from http://asciitable.com/ 31 | // 32 | `define LINE_FEED 8'h0A 33 | `define CARRIAGE_RETURN 8'h0D 34 | `define SPACE_CHAR 8'h20 35 | `define NUMBER_0 8'h30 36 | `define NUMBER_9 8'h39 37 | `define LETTER_A 8'h41 38 | `define LETTER_Z 8'h5A 39 | `define LETTER_a 8'h61 40 | `define LETTER_f 8'h66 41 | `define LETTER_z 8'h7a 42 | -------------------------------------------------------------------------------- /simulation/rtl_sims/isim_rtl_sim.f: -------------------------------------------------------------------------------- 1 | verilog work ../../tasks/uart_tasks.v -i ../../tasks/ 2 | verilog work ../../testbench/testbench.v -i ../../tasks/ 3 | verilog work ../../testbench/dump.v 4 | 5 | verilog work ../../behavioral/wb_uart/raminfr.v -i ../../behavioral/wb_uart/ 6 | verilog work ../../behavioral/wb_uart/uart_debug_if.v -i ../../behavioral/wb_uart/ 7 | verilog work ../../behavioral/wb_uart/uart_receiver.v -i ../../behavioral/wb_uart/ 8 | verilog work ../../behavioral/wb_uart/uart_regs.v -i ../../behavioral/wb_uart/ 9 | verilog work ../../behavioral/wb_uart/uart_rfifo.v -i ../../behavioral/wb_uart/ 10 | verilog work ../../behavioral/wb_uart/uart_sync_flops.v -i ../../behavioral/wb_uart/ 11 | verilog work ../../behavioral/wb_uart/uart_tfifo.v -i ../../behavioral/wb_uart/ 12 | verilog work ../../behavioral/wb_uart/uart_top.v -i ../../behavioral/wb_uart/ 13 | verilog work ../../behavioral/wb_uart/uart_transmitter.v -i ../../behavioral/wb_uart/ 14 | verilog work ../../behavioral/wb_uart/uart_wb.v -i ../../behavioral/wb_uart/ 15 | 16 | verilog work ../../behavioral/wb_master/wb_mast_model.v -i ../../behavioral/wb_master/ 17 | 18 | 19 | 20 | verilog work ../../rtl/uart.v 21 | verilog work ../../rtl/uart_echo.v 22 | verilog work ../../rtl/uart_fifo.v 23 | verilog work ../../rtl/fifo.v 24 | 25 | verilog work /data/pace/scratch03/tractp1/xilinx/14.7/ISE_DS/PlanAhead/data/verilog/src/glbl.v 26 | 27 | 28 | -------------------------------------------------------------------------------- /tasks/uart_tasks.v: -------------------------------------------------------------------------------- 1 | // -*- Mode: Verilog -*- 2 | // Filename : uart_tasks.v 3 | // Description : UART Tasks 4 | // Author : Philip Tracton 5 | // Created On : Mon Apr 20 16:12:43 2015 6 | // Last Modified By: Philip Tracton 7 | // Last Modified On: Mon Apr 20 16:12:43 2015 8 | // Update Count : 0 9 | // Status : Unknown, Use with caution! 10 | 11 | 12 | `timescale 1ns/1ns 13 | `include "includes.v" 14 | 15 | module uart_tasks; 16 | 17 | // Configure WB UART in testbench 18 | // 115200, 8N1 19 | // 20 | task uart_config; 21 | begin 22 | 23 | $display("\033[93mTASK: UART Configure\033[0m"); 24 | 25 | @(posedge `UART_CLK); 26 | //Turn on receive data interrupt 27 | `UART_MASTER0.wb_wr1(32'hFFFF0001, 4'h4, 32'h00010000); 28 | 29 | @(posedge `UART_CLK); 30 | //FIFO Control, interrupt for each byte, clear fifos and enable 31 | `UART_MASTER0.wb_wr1(32'hFFFF0002, 4'h2, 32'h00000700); 32 | 33 | @(posedge `UART_CLK); 34 | //Line Control, enable writting to the baud rate registers 35 | `UART_MASTER0.wb_wr1(32'hFFFF0003, 4'h1, 32'h00000080); 36 | 37 | @(posedge `UART_CLK); 38 | //Baud Rate LSB 39 | `UART_MASTER0.wb_wr1(32'hFFFF0000, 4'h0, 32'h0000001A); //115200bps from 50 MHz 40 | 41 | @(posedge `UART_CLK); 42 | //Baud Rate MSB 43 | `UART_MASTER0.wb_wr1(32'hFFFF0001, 4'h4, 32'h00000000); 44 | 45 | @(posedge `UART_CLK); 46 | //Line Control, 8 bits data, 1 stop bit, no parity 47 | `UART_MASTER0.wb_wr1(32'hFFFF0003, 4'h1, 32'h00000003); 48 | end 49 | endtask // uart_config 50 | 51 | 52 | // 53 | // Write a character to WB UART and catch with FPGA UART 54 | // 55 | task uart_write_char; 56 | input [7:0] char; 57 | begin 58 | 59 | // 60 | // Write the character to the WB UART to send to FPGA UART 61 | // 62 | @(posedge `UART_CLK); 63 | $display("TASK: UART Write = %c @ %d", char, $time); 64 | `UART_MASTER0.wb_wr1(32'hFFFF0000, 4'h0, {24'h000000, char}); 65 | end 66 | endtask // uart_write_char 67 | 68 | // 69 | // Read a character with WB UART that was sent from FPGA UART 70 | // 71 | task uart_read_char; 72 | input [7:0] expected; 73 | begin 74 | $display("Reading 0x%x @ %d", expected, $time); 75 | 76 | if (!testbench.uart0_int) 77 | @(posedge testbench.uart0_int); 78 | 79 | `UART_MASTER0.wb_rd1(32'hFFFF0000, 4'h0, testbench.read_word); 80 | $display("TASK: UART Read = %c @ %d", testbench.read_word, $time); 81 | if (testbench.read_word != expected) 82 | begin 83 | $display("\033[1;31mFAIL: UART Read = 0x%h NOT 0x%h @ %d\033[0m", testbench.read_word[7:0], expected, $time); 84 | `test_failed <= 1; 85 | end 86 | @(posedge testbench.clk_tb); 87 | end 88 | endtask // uart_read_char 89 | 90 | 91 | 92 | 93 | 94 | endmodule // uart_tasks 95 | -------------------------------------------------------------------------------- /tools/run_sim.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | """ 4 | run_sim.py 5 | 6 | Run FPGA simulations via Icarus, NCVerilog, Modelsim or Isim. 7 | 8 | """ 9 | 10 | import json 11 | import os 12 | import shlex 13 | import subprocess 14 | import sys 15 | import argparse 16 | 17 | 18 | def which(program): 19 | """ 20 | Find the path to an executable program 21 | """ 22 | 23 | def is_exe(fpath): 24 | """ 25 | Return True is the fpath exists and is executable. This is needed since the 26 | executables are specifed in the JSON files, but not the path to them. The 27 | executables may be in different locations based on which PC is running this. 28 | """ 29 | return os.path.isfile(fpath) and os.access(fpath, os.X_OK) 30 | 31 | fpath, fname = os.path.split(program) 32 | if fpath: 33 | if is_exe(program): 34 | return program 35 | else: 36 | for path in os.environ["PATH"].split(os.pathsep): 37 | path = path.strip('"') 38 | exe_file = os.path.join(path, program) 39 | if is_exe(exe_file): 40 | return exe_file 41 | 42 | return None 43 | 44 | if __name__ == "__main__": 45 | parser = argparse.ArgumentParser( 46 | description='Run FPGA Simulation') 47 | parser.add_argument("-D", "--debug", 48 | help="Debug this script", 49 | action="store_true") 50 | parser.add_argument("--icarus", 51 | help="Use Icarus Verilog", 52 | action="store_true") 53 | parser.add_argument("--ncverilog", 54 | help="Use NCVerilog", 55 | action="store_true") 56 | parser.add_argument("--modelsim", 57 | help="Use Altera Modelsim", 58 | action="store_true") 59 | parser.add_argument("--isim", 60 | help="Use Xilinx ISim", 61 | action="store_true") 62 | parser.add_argument("--xsim", 63 | help="Use Xilinx Vivado XSim", 64 | action="store_true") 65 | 66 | 67 | args = parser.parse_args() 68 | if args.debug: 69 | print(args) 70 | 71 | if args.icarus: 72 | json_file = "../../configurations/simulate_iverilog.json" 73 | if args.ncverilog: 74 | json_file = "../../configurations/simulate_ncverilog.json" 75 | if args.modelsim: 76 | json_file = "../../configurations/simulate_modelsim.json" 77 | if args.isim or args.xsim: 78 | json_file = "../../configurations/simulate_isim.json" 79 | 80 | try: 81 | f = open(json_file, "r") 82 | json_data = json.load(f) 83 | except: 84 | print("Failed to open %s" % (json_file)) 85 | sys.exit(-1) 86 | 87 | flow_steps = json_data['flow_steps'] 88 | print(flow_steps) 89 | 90 | for step in sorted(flow_steps.keys()): 91 | print("Running Step: %s " % step) 92 | executable = json_data['flow'][flow_steps[step]]['executable'] 93 | arguments = json_data['flow'][flow_steps[step]]['arguments'] 94 | executable = which(executable) 95 | print(executable) 96 | if (arguments == None): 97 | command = executable 98 | else: 99 | command = executable + " " + arguments 100 | 101 | print(command) 102 | command = shlex.split(command) 103 | p = subprocess.Popen(command) 104 | p.communicate() 105 | -------------------------------------------------------------------------------- /behavioral/wb_master/wb_model_defines.v: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | //// //// 3 | //// WISHBONE Model Definitions //// 4 | //// //// 5 | //// //// 6 | //// Author: Rudolf Usselmann //// 7 | //// rudi@asics.ws //// 8 | //// //// 9 | //// //// 10 | ///////////////////////////////////////////////////////////////////// 11 | //// //// 12 | //// Copyright (C) 2000-2002 Rudolf Usselmann //// 13 | //// www.asics.ws //// 14 | //// rudi@asics.ws //// 15 | //// //// 16 | //// This source file may be used and distributed without //// 17 | //// restriction provided that this copyright statement is not //// 18 | //// removed from the file and that any derivative work contains //// 19 | //// the original copyright notice and the associated disclaimer.//// 20 | //// //// 21 | //// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// 22 | //// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// 23 | //// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// 24 | //// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// 25 | //// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// 26 | //// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// 27 | //// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// 28 | //// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// 29 | //// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// 30 | //// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// 31 | //// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// 32 | //// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// 33 | //// POSSIBILITY OF SUCH DAMAGE. //// 34 | //// //// 35 | ///////////////////////////////////////////////////////////////////// 36 | 37 | // CVS Log 38 | // 39 | // $Id: wb_model_defines.v.rca 1.1.1.1 Tue Jun 7 09:38:58 2011 copew1 Experimental haskis1 haskis1 $ 40 | // 41 | // $Date: Tue Jun 7 09:38:58 2011 $ 42 | // $Revision: 1.1.1.1 $ 43 | // $Author: copew1 $ 44 | // $Locker: haskis1 haskis1 $ 45 | // $State: Experimental $ 46 | // 47 | // Change History: 48 | // $Log: wb_model_defines.v.rca $ 49 | // 50 | // Revision: 1.1.1.1 Tue Jun 7 09:38:58 2011 copew1 51 | // first stab at merging s0903a branch. 52 | // 53 | // Revision: 1.1 Fri Jun 3 12:43:38 2011 tractp1 54 | // wishbone master to control UART in test bench 55 | // Revision 1.2 2002/10/03 05:40:03 rudi 56 | // Fixed a minor bug in parameter passing, updated headers and specification. 57 | // 58 | // Revision 1.1.1.1 2001/10/19 11:04:23 rudi 59 | // WISHBONE CONMAX IP Core 60 | // 61 | // 62 | // 63 | // 64 | // 65 | // 66 | 67 | `timescale 1ns / 10ps 68 | -------------------------------------------------------------------------------- /rtl/uart_echo.v: -------------------------------------------------------------------------------- 1 | // -*- Mode: Verilog -*- 2 | // Filename : uart_echo.v 3 | // Description : FPGA Top Level for UART Echo 4 | // Author : Philip Tracton 5 | // Created On : Wed Apr 22 12:30:26 2015 6 | // Last Modified By: Philip Tracton 7 | // Last Modified On: Wed Apr 22 12:30:26 2015 8 | // Update Count : 0 9 | // Status : Unknown, Use with caution! 10 | 11 | module uart_echo (/*AUTOARG*/ 12 | // Outputs 13 | TX, 14 | // Inputs 15 | CLK, RESET, RX 16 | ) ; 17 | 18 | //--------------------------------------------------------------------------- 19 | // 20 | // PARAMETERS 21 | // 22 | //--------------------------------------------------------------------------- 23 | 24 | //--------------------------------------------------------------------------- 25 | // 26 | // PORTS 27 | // 28 | //--------------------------------------------------------------------------- 29 | input CLK; 30 | input RESET; 31 | input RX; 32 | output TX; 33 | 34 | 35 | //--------------------------------------------------------------------------- 36 | // 37 | // Registers 38 | // 39 | //--------------------------------------------------------------------------- 40 | /*AUTOREG*/ 41 | reg [7:0] tx_byte; 42 | reg transmit; 43 | reg rx_fifo_pop; 44 | 45 | //--------------------------------------------------------------------------- 46 | // 47 | // WIRES 48 | // 49 | //--------------------------------------------------------------------------- 50 | /*AUTOWIRE*/ 51 | 52 | wire [7:0] rx_byte; 53 | wire irq; 54 | wire busy; 55 | wire tx_fifo_full; 56 | wire rx_fifo_empty; 57 | wire is_transmitting; 58 | 59 | //--------------------------------------------------------------------------- 60 | // 61 | // COMBINATIONAL LOGIC 62 | // 63 | //--------------------------------------------------------------------------- 64 | 65 | 66 | 67 | //--------------------------------------------------------------------------- 68 | // 69 | // SEQUENTIAL LOGIC 70 | // 71 | //--------------------------------------------------------------------------- 72 | 73 | 74 | uart_fifo uart_fifo( 75 | // Outputs 76 | .rx_byte (rx_byte[7:0]), 77 | .tx (TX), 78 | .irq (irq), 79 | .busy (busy), 80 | .tx_fifo_full (tx_fifo_full), 81 | .rx_fifo_empty (rx_fifo_empty), 82 | // .is_transmitting (is_transmitting), 83 | // Inputs 84 | .tx_byte (tx_byte[7:0]), 85 | .clk (CLK), 86 | .rst (RESET), 87 | .rx (RX), 88 | .transmit (transmit), 89 | .rx_fifo_pop (rx_fifo_pop)); 90 | 91 | // 92 | // If we get an interrupt and the tx fifo is not full, read the receive byte 93 | // and send it back as the transmit byte, signal transmit and pop the byte from 94 | // the receive FIFO. 95 | // 96 | always @(posedge CLK) 97 | if (RESET) begin 98 | tx_byte <= 8'h00; 99 | transmit <= 1'b0; 100 | rx_fifo_pop <= 1'b0; 101 | end else begin 102 | if (!rx_fifo_empty & !tx_fifo_full & !transmit /*& !is_transmitting*/) begin 103 | tx_byte <= rx_byte; 104 | transmit <= 1'b1; 105 | rx_fifo_pop <= 1'b1; 106 | end else begin 107 | tx_byte <= 8'h00; 108 | transmit <= 1'b0; 109 | rx_fifo_pop <= 1'b0; 110 | end 111 | end // else: !if(RESET) 112 | 113 | 114 | 115 | endmodule // uart_echo 116 | -------------------------------------------------------------------------------- /behavioral/wb_uart/timescale.v: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | //// //// 3 | //// timescale.v //// 4 | //// //// 5 | //// //// 6 | //// This file is part of the "UART 16550 compatible" project //// 7 | //// http://www.opencores.org/cores/uart16550/ //// 8 | //// //// 9 | //// Documentation related to this project: //// 10 | //// - http://www.opencores.org/cores/uart16550/ //// 11 | //// //// 12 | //// Projects compatibility: //// 13 | //// - WISHBONE //// 14 | //// RS232 Protocol //// 15 | //// 16550D uart (mostly supported) //// 16 | //// //// 17 | //// Overview (main Features): //// 18 | //// Defines of the Core //// 19 | //// //// 20 | //// Known problems (limits): //// 21 | //// None //// 22 | //// //// 23 | //// To Do: //// 24 | //// Nothing. //// 25 | //// //// 26 | //// Author(s): //// 27 | //// - gorban@opencores.org //// 28 | //// - Jacob Gorban //// 29 | //// - Igor Mohor (igorm@opencores.org) //// 30 | //// //// 31 | //// Created: 2001/05/12 //// 32 | //// Last Updated: 2001/05/17 //// 33 | //// (See log for the revision history) //// 34 | //// //// 35 | //// //// 36 | ////////////////////////////////////////////////////////////////////// 37 | //// //// 38 | //// Copyright (C) 2000, 2001 Authors //// 39 | //// //// 40 | //// This source file may be used and distributed without //// 41 | //// restriction provided that this copyright statement is not //// 42 | //// removed from the file and that any derivative work contains //// 43 | //// the original copyright notice and the associated disclaimer. //// 44 | //// //// 45 | //// This source file is free software; you can redistribute it //// 46 | //// and/or modify it under the terms of the GNU Lesser General //// 47 | //// Public License as published by the Free Software Foundation; //// 48 | //// either version 2.1 of the License, or (at your option) any //// 49 | //// later version. //// 50 | //// //// 51 | //// This source is distributed in the hope that it will be //// 52 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// 53 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// 54 | //// PURPOSE. See the GNU Lesser General Public License for more //// 55 | //// details. //// 56 | //// //// 57 | //// You should have received a copy of the GNU Lesser General //// 58 | //// Public License along with this source; if not, download it //// 59 | //// from http://www.opencores.org/lgpl.shtml //// 60 | //// //// 61 | ////////////////////////////////////////////////////////////////////// 62 | // Timescale define 63 | 64 | `timescale 1ns/10ps 65 | -------------------------------------------------------------------------------- /fpga/xilinx/basys3/basys3.xpr: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 65 | 66 | 67 | 68 | 69 | 75 | 76 | 77 | 78 | 79 | 82 | 83 | 85 | 86 | 88 | 89 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /testbench/testbench.v: -------------------------------------------------------------------------------- 1 | // -*- Mode: Verilog -*- 2 | // Filename : testbench.v 3 | // Description : UART RTL Test bench 4 | // Author : Philip Tracton 5 | // Created On : Mon Apr 20 16:05:13 2015 6 | // Last Modified By: Philip Tracton 7 | // Last Modified On: Mon Apr 20 16:05:13 2015 8 | // Update Count : 0 9 | // Status : Unknown, Use with caution! 10 | 11 | `timescale 1ns/1ns 12 | 13 | `include "includes.v" 14 | 15 | module testbench (/*AUTOARG*/ ) ; 16 | 17 | // 18 | // Free Running 50 MHz Clock 19 | // 20 | reg clk_tb; 21 | 22 | parameter _clk_50mhz_high = 10, 23 | _clk_50mhz_low = 10, 24 | _clk_50mhz_period = _clk_50mhz_high + _clk_50mhz_low; 25 | 26 | initial 27 | begin 28 | clk_tb <= 'b0; 29 | forever 30 | begin 31 | #(_clk_50mhz_low) clk_tb = 1; 32 | #(_clk_50mhz_high) clk_tb = 0; 33 | end 34 | end 35 | 36 | // 37 | // Free Running 100 MHz Clock 38 | // 39 | reg clk_100mhz; 40 | 41 | parameter _clk_100mhz_high = 5, 42 | _clk_100mhz_low = 5, 43 | _clk_100mhz_period = _clk_100mhz_high + _clk_100mhz_low; 44 | 45 | initial 46 | begin 47 | clk_100mhz <= 'b0; 48 | forever 49 | begin 50 | #(_clk_100mhz_low) clk_100mhz = 1; 51 | #(_clk_100mhz_high) clk_100mhz = 0; 52 | end 53 | end 54 | 55 | // 56 | // Asynch. Reset to device 57 | // 58 | reg reset_tb; 59 | initial 60 | begin 61 | reset_tb = 0; 62 | #1 reset_tb = 1; 63 | #200 reset_tb = 0; 64 | end 65 | 66 | 67 | uart_echo dut( 68 | .TX(UART0_TX), 69 | .CLK(clk_100mhz), 70 | .RESET(reset_tb), 71 | .RX(UART0_RX) 72 | ) ; 73 | 74 | // 75 | // Simulation tools 76 | // 77 | reg test_failed; 78 | reg test_passed; 79 | reg [31:0] read_word; 80 | initial begin 81 | test_failed <= 1'b0; 82 | read_word <= 32'b0; 83 | end 84 | 85 | always @(posedge test_passed) 86 | if (test_passed) begin 87 | $display("*** TEST PASSED ***"); 88 | #1000; 89 | $finish; 90 | end 91 | 92 | always @(posedge test_failed) 93 | if (test_failed) begin 94 | $display("*** TEST FAILED ***"); 95 | #50; 96 | $finish; 97 | end 98 | 99 | /**************************************************************************** 100 | UART 0 -- This is used for CLI Interfacing 101 | 102 | The WB UART16550 from opencores is used here to simulate a UART on the other end 103 | of the cable. It will allow us to send/receive characters to the NGMCU firmware 104 | ***************************************************************************/ 105 | 106 | wire [31:0] uart0_adr; 107 | wire [31:0] uart0_dat_o; 108 | wire [31:0] uart0_dat_i; 109 | wire [3:0] uart0_sel; 110 | wire uart0_cyc; 111 | wire uart0_stb; 112 | wire uart0_we; 113 | wire uart0_ack; 114 | wire uart0_int; 115 | 116 | 117 | 118 | assign uart0_dat_o[31:8] = 'b0; 119 | 120 | 121 | 122 | uart_top uart0( 123 | .wb_clk_i(clk_tb), 124 | .wb_rst_i(reset_tb), 125 | 126 | .wb_adr_i(uart0_adr[4:0]), 127 | .wb_dat_o(uart0_dat_o), 128 | .wb_dat_i(uart0_dat_i), 129 | .wb_sel_i(uart0_sel), 130 | .wb_cyc_i(uart0_cyc), 131 | .wb_stb_i(uart0_stb), 132 | .wb_we_i(uart0_we), 133 | .wb_ack_o(uart0_ack), 134 | .int_o(uart0_int), 135 | .stx_pad_o(UART0_RX), 136 | .srx_pad_i(UART0_TX), 137 | 138 | .rts_pad_o(), 139 | .cts_pad_i(1'b0), 140 | .dtr_pad_o(), 141 | .dsr_pad_i(1'b0), 142 | .ri_pad_i(1'b0), 143 | .dcd_pad_i(1'b0), 144 | 145 | .baud_o() 146 | ); 147 | 148 | 149 | wb_mast uart_master0( 150 | .clk (clk_tb), 151 | .rst (reset_tb), 152 | .adr (uart0_adr), 153 | .din (uart0_dat_o), 154 | .dout(uart0_dat_i), 155 | .cyc (uart0_cyc), 156 | .stb (uart0_stb), 157 | .sel (uart0_sel), 158 | .we (uart0_we ), 159 | .ack (uart0_ack), 160 | .err (1'b0), 161 | .rty (1'b0) 162 | ); 163 | 164 | 165 | // 166 | // Test Case 167 | // 168 | initial begin 169 | test_failed <= 1'b0; 170 | test_passed <= 1'b0; 171 | 172 | @(negedge reset_tb); 173 | $display("RESET RELEASED %d", $time); 174 | repeat(10)@(posedge clk_tb); 175 | 176 | `UART_CONFIG(); 177 | `UART_WRITE_CHAR("A"); 178 | `UART_WRITE_CHAR("B"); 179 | `UART_WRITE_CHAR("C"); 180 | `UART_WRITE_CHAR("D"); 181 | `UART_WRITE_CHAR("E"); 182 | 183 | repeat(100)@(posedge clk_tb); 184 | 185 | `UART_READ_CHAR("A"); 186 | `UART_READ_CHAR("B"); 187 | `UART_READ_CHAR("C"); 188 | `UART_READ_CHAR("D"); 189 | `UART_READ_CHAR("E"); 190 | 191 | repeat(100)@(posedge clk_tb); 192 | test_passed <= 1'b1; 193 | 194 | end // initial begin 195 | 196 | uart_tasks uart_tasks(); 197 | 198 | 199 | endmodule // testbench 200 | -------------------------------------------------------------------------------- /behavioral/wb_uart/uart_sync_flops.v: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | //// //// 3 | //// uart_sync_flops.v //// 4 | //// //// 5 | //// //// 6 | //// This file is part of the "UART 16550 compatible" project //// 7 | //// http://www.opencores.org/cores/uart16550/ //// 8 | //// //// 9 | //// Documentation related to this project: //// 10 | //// - http://www.opencores.org/cores/uart16550/ //// 11 | //// //// 12 | //// Projects compatibility: //// 13 | //// - WISHBONE //// 14 | //// RS232 Protocol //// 15 | //// 16550D uart (mostly supported) //// 16 | //// //// 17 | //// Overview (main Features): //// 18 | //// UART core receiver logic //// 19 | //// //// 20 | //// Known problems (limits): //// 21 | //// None known //// 22 | //// //// 23 | //// To Do: //// 24 | //// Thourough testing. //// 25 | //// //// 26 | //// Author(s): //// 27 | //// - Andrej Erzen (andreje@flextronics.si) //// 28 | //// - Tadej Markovic (tadejm@flextronics.si) //// 29 | //// //// 30 | //// Created: 2004/05/20 //// 31 | //// Last Updated: 2004/05/20 //// 32 | //// (See log for the revision history) //// 33 | //// //// 34 | //// //// 35 | ////////////////////////////////////////////////////////////////////// 36 | //// //// 37 | //// Copyright (C) 2000, 2001 Authors //// 38 | //// //// 39 | //// This source file may be used and distributed without //// 40 | //// restriction provided that this copyright statement is not //// 41 | //// removed from the file and that any derivative work contains //// 42 | //// the original copyright notice and the associated disclaimer. //// 43 | //// //// 44 | //// This source file is free software; you can redistribute it //// 45 | //// and/or modify it under the terms of the GNU Lesser General //// 46 | //// Public License as published by the Free Software Foundation; //// 47 | //// either version 2.1 of the License, or (at your option) any //// 48 | //// later version. //// 49 | //// //// 50 | //// This source is distributed in the hope that it will be //// 51 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// 52 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// 53 | //// PURPOSE. See the GNU Lesser General Public License for more //// 54 | //// details. //// 55 | //// //// 56 | //// You should have received a copy of the GNU Lesser General //// 57 | //// Public License along with this source; if not, download it //// 58 | //// from http://www.opencores.org/lgpl.shtml //// 59 | //// //// 60 | ////////////////////////////////////////////////////////////////////// 61 | // 62 | // CVS Revision History 63 | // 64 | // $Log: uart_sync_flops.v.rca $ 65 | // 66 | // Revision: 1.1.1.1 Tue Jun 7 09:39:01 2011 copew1 67 | // first stab at merging s0903a branch. 68 | // 69 | // Revision: 1.1 Fri Jun 3 12:44:14 2011 tractp1 70 | // UART in test bench to send/receive ASCII bytes with FPGA UART and 71 | // command processing task in firmware 72 | // 73 | 74 | 75 | `include "timescale.v" 76 | 77 | 78 | module uart_sync_flops 79 | ( 80 | // internal signals 81 | rst_i, 82 | clk_i, 83 | stage1_rst_i, 84 | stage1_clk_en_i, 85 | async_dat_i, 86 | sync_dat_o 87 | ); 88 | 89 | parameter Tp = 1; 90 | parameter width = 1; 91 | parameter init_value = 1'b0; 92 | 93 | input rst_i; // reset input 94 | input clk_i; // clock input 95 | input stage1_rst_i; // synchronous reset for stage 1 FF 96 | input stage1_clk_en_i; // synchronous clock enable for stage 1 FF 97 | input [width-1:0] async_dat_i; // asynchronous data input 98 | output [width-1:0] sync_dat_o; // synchronous data output 99 | 100 | 101 | // 102 | // Interal signal declarations 103 | // 104 | 105 | reg [width-1:0] sync_dat_o; 106 | reg [width-1:0] flop_0; 107 | 108 | 109 | // first stage 110 | always @ (posedge clk_i or posedge rst_i) 111 | begin 112 | if (rst_i) 113 | flop_0 <= #Tp {width{init_value}}; 114 | else 115 | flop_0 <= #Tp async_dat_i; 116 | end 117 | 118 | // second stage 119 | always @ (posedge clk_i or posedge rst_i) 120 | begin 121 | if (rst_i) 122 | sync_dat_o <= #Tp {width{init_value}}; 123 | else if (stage1_rst_i) 124 | sync_dat_o <= #Tp {width{init_value}}; 125 | else if (stage1_clk_en_i) 126 | sync_dat_o <= #Tp flop_0; 127 | end 128 | 129 | endmodule 130 | -------------------------------------------------------------------------------- /behavioral/wb_uart/raminfr.v: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | //// //// 3 | //// raminfr.v //// 4 | //// //// 5 | //// //// 6 | //// This file is part of the "UART 16550 compatible" project //// 7 | //// http://www.opencores.org/cores/uart16550/ //// 8 | //// //// 9 | //// Documentation related to this project: //// 10 | //// - http://www.opencores.org/cores/uart16550/ //// 11 | //// //// 12 | //// Projects compatibility: //// 13 | //// - WISHBONE //// 14 | //// RS232 Protocol //// 15 | //// 16550D uart (mostly supported) //// 16 | //// //// 17 | //// Overview (main Features): //// 18 | //// Inferrable Distributed RAM for FIFOs //// 19 | //// //// 20 | //// Known problems (limits): //// 21 | //// None . //// 22 | //// //// 23 | //// To Do: //// 24 | //// Nothing so far. //// 25 | //// //// 26 | //// Author(s): //// 27 | //// - gorban@opencores.org //// 28 | //// - Jacob Gorban //// 29 | //// //// 30 | //// Created: 2002/07/22 //// 31 | //// Last Updated: 2002/07/22 //// 32 | //// (See log for the revision history) //// 33 | //// //// 34 | //// //// 35 | ////////////////////////////////////////////////////////////////////// 36 | //// //// 37 | //// Copyright (C) 2000, 2001 Authors //// 38 | //// //// 39 | //// This source file may be used and distributed without //// 40 | //// restriction provided that this copyright statement is not //// 41 | //// removed from the file and that any derivative work contains //// 42 | //// the original copyright notice and the associated disclaimer. //// 43 | //// //// 44 | //// This source file is free software; you can redistribute it //// 45 | //// and/or modify it under the terms of the GNU Lesser General //// 46 | //// Public License as published by the Free Software Foundation; //// 47 | //// either version 2.1 of the License, or (at your option) any //// 48 | //// later version. //// 49 | //// //// 50 | //// This source is distributed in the hope that it will be //// 51 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// 52 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// 53 | //// PURPOSE. See the GNU Lesser General Public License for more //// 54 | //// details. //// 55 | //// //// 56 | //// You should have received a copy of the GNU Lesser General //// 57 | //// Public License along with this source; if not, download it //// 58 | //// from http://www.opencores.org/lgpl.shtml //// 59 | //// //// 60 | ////////////////////////////////////////////////////////////////////// 61 | // 62 | // CVS Revision History 63 | // 64 | // $Log: raminfr.v.rca $ 65 | // 66 | // Revision: 1.1.1.1 Tue Jun 7 09:39:01 2011 copew1 67 | // first stab at merging s0903a branch. 68 | // 69 | // Revision: 1.1 Fri Jun 3 12:44:14 2011 tractp1 70 | // UART in test bench to send/receive ASCII bytes with FPGA UART and 71 | // command processing task in firmware 72 | // Revision 1.1 2002/07/22 23:02:23 gorban 73 | // Bug Fixes: 74 | // * Possible loss of sync and bad reception of stop bit on slow baud rates fixed. 75 | // Problem reported by Kenny.Tung. 76 | // * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers. 77 | // 78 | // Improvements: 79 | // * Made FIFO's as general inferrable memory where possible. 80 | // So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx). 81 | // This saves about 1/3 of the Slice count and reduces P&R and synthesis times. 82 | // 83 | // * Added optional baudrate output (baud_o). 84 | // This is identical to BAUDOUT* signal on 16550 chip. 85 | // It outputs 16xbit_clock_rate - the divided clock. 86 | // It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use. 87 | // 88 | 89 | //Following is the Verilog code for a dual-port RAM with asynchronous read. 90 | module raminfr 91 | (clk, we, a, dpra, di, dpo); 92 | 93 | parameter addr_width = 4; 94 | parameter data_width = 8; 95 | parameter depth = 16; 96 | 97 | input clk; 98 | input we; 99 | input [addr_width-1:0] a; 100 | input [addr_width-1:0] dpra; 101 | input [data_width-1:0] di; 102 | //output [data_width-1:0] spo; 103 | output [data_width-1:0] dpo; 104 | reg [data_width-1:0] ram [depth-1:0]; 105 | 106 | wire [data_width-1:0] dpo; 107 | wire [data_width-1:0] di; 108 | wire [addr_width-1:0] a; 109 | wire [addr_width-1:0] dpra; 110 | 111 | always @(posedge clk) begin 112 | if (we) 113 | ram[a] <= di; 114 | end 115 | // assign spo = ram[a]; 116 | assign dpo = ram[dpra]; 117 | endmodule 118 | 119 | -------------------------------------------------------------------------------- /behavioral/wb_uart/uart_debug_if.v: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | //// //// 3 | //// uart_debug_if.v //// 4 | //// //// 5 | //// //// 6 | //// This file is part of the "UART 16550 compatible" project //// 7 | //// http://www.opencores.org/cores/uart16550/ //// 8 | //// //// 9 | //// Documentation related to this project: //// 10 | //// - http://www.opencores.org/cores/uart16550/ //// 11 | //// //// 12 | //// Projects compatibility: //// 13 | //// - WISHBONE //// 14 | //// RS232 Protocol //// 15 | //// 16550D uart (mostly supported) //// 16 | //// //// 17 | //// Overview (main Features): //// 18 | //// UART core debug interface. //// 19 | //// //// 20 | //// Author(s): //// 21 | //// - gorban@opencores.org //// 22 | //// - Jacob Gorban //// 23 | //// //// 24 | //// Created: 2001/12/02 //// 25 | //// (See log for the revision history) //// 26 | //// //// 27 | ////////////////////////////////////////////////////////////////////// 28 | //// //// 29 | //// Copyright (C) 2000, 2001 Authors //// 30 | //// //// 31 | //// This source file may be used and distributed without //// 32 | //// restriction provided that this copyright statement is not //// 33 | //// removed from the file and that any derivative work contains //// 34 | //// the original copyright notice and the associated disclaimer. //// 35 | //// //// 36 | //// This source file is free software; you can redistribute it //// 37 | //// and/or modify it under the terms of the GNU Lesser General //// 38 | //// Public License as published by the Free Software Foundation; //// 39 | //// either version 2.1 of the License, or (at your option) any //// 40 | //// later version. //// 41 | //// //// 42 | //// This source is distributed in the hope that it will be //// 43 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// 44 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// 45 | //// PURPOSE. See the GNU Lesser General Public License for more //// 46 | //// details. //// 47 | //// //// 48 | //// You should have received a copy of the GNU Lesser General //// 49 | //// Public License along with this source; if not, download it //// 50 | //// from http://www.opencores.org/lgpl.shtml //// 51 | //// //// 52 | ////////////////////////////////////////////////////////////////////// 53 | // 54 | // CVS Revision History 55 | // 56 | // $Log: uart_debug_if.v.rca $ 57 | // 58 | // Revision: 1.1.1.1 Tue Jun 7 09:39:01 2011 copew1 59 | // first stab at merging s0903a branch. 60 | // 61 | // Revision: 1.1 Fri Jun 3 12:44:14 2011 tractp1 62 | // UART in test bench to send/receive ASCII bytes with FPGA UART and 63 | // command processing task in firmware 64 | // Revision 1.4 2002/07/22 23:02:23 gorban 65 | // Bug Fixes: 66 | // * Possible loss of sync and bad reception of stop bit on slow baud rates fixed. 67 | // Problem reported by Kenny.Tung. 68 | // * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers. 69 | // 70 | // Improvements: 71 | // * Made FIFO's as general inferrable memory where possible. 72 | // So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx). 73 | // This saves about 1/3 of the Slice count and reduces P&R and synthesis times. 74 | // 75 | // * Added optional baudrate output (baud_o). 76 | // This is identical to BAUDOUT* signal on 16550 chip. 77 | // It outputs 16xbit_clock_rate - the divided clock. 78 | // It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use. 79 | // 80 | // Revision 1.3 2001/12/19 08:40:03 mohor 81 | // Warnings fixed (unused signals removed). 82 | // 83 | // Revision 1.2 2001/12/12 22:17:30 gorban 84 | // some synthesis bugs fixed 85 | // 86 | // Revision 1.1 2001/12/04 21:14:16 gorban 87 | // committed the debug interface file 88 | // 89 | 90 | // synopsys translate_off 91 | `include "timescale.v" 92 | // synopsys translate_on 93 | 94 | `include "uart_defines.v" 95 | 96 | module uart_debug_if (/*AUTOARG*/ 97 | // Outputs 98 | wb_dat32_o, 99 | // Inputs 100 | wb_adr_i, ier, iir, fcr, mcr, lcr, msr, 101 | lsr, rf_count, tf_count, tstate, rstate 102 | ) ; 103 | 104 | input [`UART_ADDR_WIDTH-1:0] wb_adr_i; 105 | output [31:0] wb_dat32_o; 106 | input [3:0] ier; 107 | input [3:0] iir; 108 | input [1:0] fcr; /// bits 7 and 6 of fcr. Other bits are ignored 109 | input [4:0] mcr; 110 | input [7:0] lcr; 111 | input [7:0] msr; 112 | input [7:0] lsr; 113 | input [`UART_FIFO_COUNTER_W-1:0] rf_count; 114 | input [`UART_FIFO_COUNTER_W-1:0] tf_count; 115 | input [2:0] tstate; 116 | input [3:0] rstate; 117 | 118 | 119 | wire [`UART_ADDR_WIDTH-1:0] wb_adr_i; 120 | reg [31:0] wb_dat32_o; 121 | 122 | always @(/*AUTOSENSE*/fcr or ier or iir or lcr or lsr or mcr or msr 123 | or rf_count or rstate or tf_count or tstate or wb_adr_i) 124 | case (wb_adr_i) 125 | // 8 + 8 + 4 + 4 + 8 126 | 5'b01000: wb_dat32_o = {msr,lcr,iir,ier,lsr}; 127 | // 5 + 2 + 5 + 4 + 5 + 3 128 | 5'b01100: wb_dat32_o = {8'b0, fcr,mcr, rf_count, rstate, tf_count, tstate}; 129 | default: wb_dat32_o = 0; 130 | endcase // case(wb_adr_i) 131 | 132 | endmodule // uart_debug_if 133 | 134 | -------------------------------------------------------------------------------- /rtl/uart_fifo.v: -------------------------------------------------------------------------------- 1 | // -*- Mode: Verilog -*- 2 | // Filename : uart_fifo.v 3 | // Description : UART FIFO RTL 4 | // Author : Philip Tracton 5 | // Created On : Mon Apr 20 16:00:09 2015 6 | // Last Modified By: Philip Tracton 7 | // Last Modified On: Mon Apr 20 16:00:09 2015 8 | // Update Count : 0 9 | // Status : Unknown, Use with caution! 10 | 11 | 12 | module uart_fifo (/*AUTOARG*/ 13 | // Outputs 14 | rx_byte, tx, irq, busy, tx_fifo_full, rx_fifo_empty, 15 | // Inputs 16 | tx_byte, clk, rst, rx, transmit, rx_fifo_pop 17 | ) ; 18 | 19 | //--------------------------------------------------------------------------- 20 | // 21 | // PARAMETERS 22 | // 23 | //--------------------------------------------------------------------------- 24 | 25 | //--------------------------------------------------------------------------- 26 | // 27 | // PORTS 28 | // 29 | //--------------------------------------------------------------------------- 30 | 31 | input [7:0] tx_byte; // The byte to send to PC. Loaded into FIFO first 32 | input clk; // 50MHz free running clock 33 | input rst; // Synchronous active high reset logic 34 | input rx; // Serial RX signal from PC 35 | input transmit; // Signal to send a byte to the PC 36 | input rx_fifo_pop; // Pop the value out of RX FIFO 37 | 38 | output [7:0] rx_byte; // First byte in FIFO that we have received 39 | output tx; // Signal from FPGA to PC for serial transmission 40 | output irq; // Receive or error or RX Full interrupt 41 | output busy; // actively receiving or transmitting when this is high 42 | output tx_fifo_full; // The TX FIFO is full when asserted no more data can be transmitted. 43 | output rx_fifo_empty; // Asserted when the RX FIFO is not holding data 44 | 45 | //--------------------------------------------------------------------------- 46 | // 47 | // Registers 48 | // 49 | //--------------------------------------------------------------------------- 50 | /*AUTOREG*/ 51 | reg tx_fifo_pop; // If there is byte to send and not sending pop a value from TX FIFO 52 | 53 | //--------------------------------------------------------------------------- 54 | // 55 | // WIRES 56 | // 57 | //--------------------------------------------------------------------------- 58 | /*AUTOWIRE*/ 59 | 60 | // Beginning of automatic wires (for undeclared instantiated-module outputs) 61 | wire is_receiving; // From uart_inst of uart.v 62 | wire is_transmitting; // From uart_inst of uart.v 63 | wire received; // From uart_inst of uart.v 64 | wire recv_error; // From uart_inst of uart.v 65 | // End of automatics 66 | 67 | 68 | wire rx_fifo_full; // Asserted when RX FIFO is full 69 | wire [7:0] rx_fifo_data_in; // Byte from UART to RX FIFO 70 | wire rx_fifo_pop; // Pop a value from the RX FIFO 71 | wire rx_fifo_empty; // Asserted when the RX FIFO is empty 72 | 73 | wire [7:0] tx_fifo_data_out; // Byte from TX FIFO to UART 74 | wire tx_fifo_full; // Asserted when the TX FIFO is FULL 75 | wire tx_fifo_empty; // Asserted when the TX FIFO is EMPTY 76 | 77 | 78 | //--------------------------------------------------------------------------- 79 | // 80 | // COMBINATIONAL LOGIC 81 | // 82 | //--------------------------------------------------------------------------- 83 | 84 | // 85 | // Assert an interrupt if we have received a byte, an error of if the rx_fifo 86 | // is full. All of these are reasons for reading this UART 87 | // 88 | assign irq = received || recv_error || rx_fifo_full; 89 | 90 | // 91 | // If we are actively receiving or transmitting, we are "busy" 92 | // 93 | assign busy = is_receiving || is_transmitting; 94 | 95 | //--------------------------------------------------------------------------- 96 | // 97 | // SEQUENTIAL LOGIC 98 | // 99 | //--------------------------------------------------------------------------- 100 | 101 | // 102 | // UART Instance. Handles the actual sending/receiving of serial data 103 | // 104 | uart uart_inst( 105 | // Outputs 106 | .tx (tx), 107 | .received (received), 108 | .rx_byte (rx_fifo_data_in), 109 | .is_receiving (is_receiving), 110 | .is_transmitting (is_transmitting), 111 | .recv_error (recv_error), 112 | // Inputs 113 | .clk (clk), 114 | .rst (rst), 115 | .rx (rx), 116 | .transmit (tx_fifo_pop), 117 | .tx_byte (tx_fifo_data_out)); 118 | 119 | 120 | // 121 | // RX FIFO takes data recevied by the UART and holds until outside module 122 | // requests data 123 | // 124 | fifo #(.DATA_WIDTH(8)) 125 | rx_fifo( 126 | // Outputs 127 | .DATA_OUT (rx_byte), 128 | .FULL (rx_fifo_full), 129 | .EMPTY (rx_fifo_empty), 130 | // Inputs 131 | .CLK (clk), 132 | .RESET (rst), 133 | .ENABLE (1'b1), 134 | .FLUSH (1'b0), 135 | .DATA_IN (rx_fifo_data_in), 136 | .PUSH (received), 137 | .POP (rx_fifo_pop)); 138 | 139 | 140 | // 141 | // TX FIFO takes data from outside module and holds it until the 142 | // UART is able to transmit it 143 | // 144 | fifo #(.DATA_WIDTH(8)) 145 | tx_fifo( 146 | // Outputs 147 | .DATA_OUT (tx_fifo_data_out), 148 | .FULL (tx_fifo_full), 149 | .EMPTY (tx_fifo_empty), 150 | // Inputs 151 | .CLK (clk), 152 | .RESET (rst), 153 | .ENABLE (1'b1), 154 | .FLUSH (1'b0), 155 | .DATA_IN (tx_byte), 156 | .PUSH (transmit), 157 | .POP (tx_fifo_pop)); 158 | 159 | // 160 | // POP from TX FIFO is it is NOT empty and we are NOT transmitting 161 | // 162 | 163 | always @(posedge clk) 164 | if (rst) begin 165 | tx_fifo_pop <= 1'b0; 166 | end else begin 167 | tx_fifo_pop <= !is_transmitting & !tx_fifo_empty; 168 | end 169 | 170 | 171 | 172 | 173 | endmodule // uart_fifo 174 | -------------------------------------------------------------------------------- /rtl/fifo.v: -------------------------------------------------------------------------------- 1 | // -*- Mode: Verilog -*- 2 | // Filename : fifo.v 3 | // Description : FIFO 4 | // Author : Philip Tracton 5 | // Created On : Tue May 27 16:03:26 2014 6 | // Last Modified By: Philip Tracton 7 | // Last Modified On: Tue May 27 16:03:26 2014 8 | // Update Count : 0 9 | // Status : Unknown, Use with caution! 10 | 11 | module fifo (/*AUTOARG*/ 12 | // Outputs 13 | DATA_OUT, FULL, EMPTY, 14 | // Inputs 15 | CLK, RESET, ENABLE, FLUSH, DATA_IN, PUSH, POP 16 | ) ; 17 | 18 | 19 | //--------------------------------------------------------------------------- 20 | // 21 | // PARAMETERS 22 | // 23 | //--------------------------------------------------------------------------- 24 | parameter DATA_WIDTH = 32; // Width of input and output data 25 | parameter ADDR_EXP = 3; // Width of our address, FIFO depth is 2^^ADDR_EXP 26 | parameter ADDR_DEPTH = 2 ** ADDR_EXP; // DO NOT DIRECTLY SET THIS ONE! 27 | 28 | //--------------------------------------------------------------------------- 29 | // 30 | // PORTS 31 | // 32 | //--------------------------------------------------------------------------- 33 | input CLK; // Clock for all logic 34 | input RESET; // Synchronous Active High Reset 35 | input ENABLE; // When asserted (1'b1), this block is active 36 | input FLUSH; // When asserted (1'b1), the FIFO is dumped out and reset to all 0 37 | input [DATA_WIDTH - 1:0] DATA_IN; // Input data stored when PUSHed 38 | input PUSH; // When asserted (1'b1), DATA_IN is stored into FIFO 39 | input POP; // When asserted (1'b1), DATA_OUT is the next value in the FIFO 40 | 41 | output [DATA_WIDTH - 1:0] DATA_OUT; // Output data from FIFO 42 | output FULL; // Asseted when there is no more space in FIFO 43 | output EMPTY; // Asserted when there is nothing in the FIFO 44 | 45 | 46 | //--------------------------------------------------------------------------- 47 | // 48 | // Registers 49 | // 50 | //--------------------------------------------------------------------------- 51 | /*AUTOREG*/ 52 | // Beginning of automatic regs (for this module's undeclared outputs) 53 | reg EMPTY; 54 | reg FULL; 55 | // End of automatics 56 | 57 | reg [DATA_WIDTH -1:0] memory[0:ADDR_DEPTH-1]; // The memory for the FIFO 58 | reg [ADDR_EXP:0] write_ptr; // Location to write to 59 | reg [ADDR_EXP:0] read_ptr; // Location to read from 60 | 61 | //--------------------------------------------------------------------------- 62 | // 63 | // WIRES 64 | // 65 | //--------------------------------------------------------------------------- 66 | /*AUTOWIRE*/ 67 | wire [DATA_WIDTH-1:0] DATA_OUT; // Top of the FIFO driven out of the module 68 | wire [ADDR_EXP:0] next_write_ptr; // Next location to write to 69 | wire [ADDR_EXP:0] next_read_ptr; // Next location to read from 70 | wire accept_write; // Asserted when we can accept this write (PUSH) 71 | wire accept_read; // Asserted when we can accept this read (POP) 72 | 73 | //--------------------------------------------------------------------------- 74 | // 75 | // COMBINATIONAL LOGIC 76 | // 77 | //--------------------------------------------------------------------------- 78 | 79 | // 80 | // Read and write pointers increment by one unless at the last address. In that 81 | // case wrap around to the beginning (0) 82 | // 83 | assign next_write_ptr = (write_ptr == ADDR_DEPTH-1) ? 0 :write_ptr + 1; 84 | assign next_read_ptr = (read_ptr == ADDR_DEPTH-1) ? 0 :read_ptr + 1; 85 | 86 | // 87 | // Only write if enabled, no flushing and not full or at the same time as a pop 88 | // 89 | assign accept_write = (PUSH && ENABLE && !FLUSH && !FULL) || (PUSH && POP && ENABLE); 90 | 91 | // 92 | // Only read if not flushing and not empty or at the same time as a push 93 | // 94 | assign accept_read = (POP && ENABLE && !FLUSH && !EMPTY) || (PUSH && POP && ENABLE); 95 | 96 | // 97 | // We are always driving the data out to be read. Pop will move to the next location 98 | // in memory 99 | // 100 | assign DATA_OUT = (ENABLE) ? memory[read_ptr]: 'b0; 101 | 102 | //--------------------------------------------------------------------------- 103 | // 104 | // SEQUENTIAL LOGIC 105 | // 106 | //--------------------------------------------------------------------------- 107 | 108 | // 109 | // Write Pointer Logic 110 | // 111 | always @(posedge CLK) 112 | if (RESET) begin 113 | write_ptr <= 'b0; 114 | end else if (ENABLE) begin 115 | if (FLUSH) begin 116 | write_ptr <= 'b0; 117 | end else begin 118 | if (accept_write) begin 119 | write_ptr <= next_write_ptr; 120 | end 121 | end 122 | end else begin 123 | write_ptr <= 'b0; 124 | end 125 | 126 | // 127 | // Read Pointer Logic 128 | // 129 | always @(posedge CLK) 130 | if (RESET) begin 131 | read_ptr <= 'b0; 132 | end else if (ENABLE) begin 133 | if (FLUSH) begin 134 | read_ptr <= 'b0; 135 | end else begin 136 | if (accept_read) begin 137 | read_ptr <= next_read_ptr; 138 | end 139 | end 140 | end else begin 141 | read_ptr <= 'b0; 142 | end 143 | 144 | // 145 | // Empty Logic 146 | // 147 | always @(posedge CLK) 148 | if (RESET) begin 149 | EMPTY <= 1'b1; 150 | end else if (ENABLE) begin 151 | if (FLUSH) begin 152 | EMPTY <= 1'b1; 153 | end else begin 154 | if (EMPTY && accept_write) begin 155 | EMPTY <= 1'b0; 156 | end 157 | if (accept_read && (next_read_ptr == write_ptr)) begin 158 | EMPTY <= 1'b1; 159 | end 160 | end 161 | end else begin 162 | EMPTY <= 1'b1; 163 | end 164 | 165 | // 166 | // Full Logic 167 | // 168 | always @(posedge CLK) 169 | if (RESET) begin 170 | FULL <= 1'b0; 171 | end else if (ENABLE) begin 172 | if (FLUSH) begin 173 | FULL <= 1'b0; 174 | end else begin 175 | if (accept_write && (next_write_ptr == read_ptr)) begin 176 | FULL <= 1; 177 | end else if (FULL && accept_read) begin 178 | FULL <= 0; 179 | end 180 | end 181 | end else begin 182 | FULL <= 1'b0; 183 | end // else: !if(ENABLE) 184 | 185 | 186 | // 187 | // FIFO Write Logic 188 | // 189 | 190 | integer i; 191 | always @(posedge CLK) 192 | if (RESET) begin 193 | for (i=0; i< (ADDR_DEPTH); i=i+1) begin 194 | memory[i] <= 'b0; 195 | end 196 | end else if (ENABLE) begin 197 | if (FLUSH) begin 198 | for (i=0; i< (ADDR_DEPTH); i=i+1) begin 199 | memory[i] <= 'b0; 200 | end 201 | end 202 | else if (accept_write) begin 203 | memory[write_ptr] <= DATA_IN; 204 | end 205 | end 206 | 207 | 208 | endmodule 209 | -------------------------------------------------------------------------------- /rtl/uart.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns / 1ps 2 | // Documented Verilog UART 3 | // Copyright (C) 2010 Timothy Goddard (tim@goddard.net.nz) 4 | // Distributed under the MIT licence. 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | // THE SOFTWARE. 23 | // 24 | module uart( 25 | input clk, // The master clock for this module 26 | input rst, // Synchronous reset. 27 | input rx, // Incoming serial line 28 | output tx, // Outgoing serial line 29 | input transmit, // Signal to transmit 30 | input [7:0] tx_byte, // Byte to transmit 31 | output received, // Indicated that a byte has been received. 32 | output [7:0] rx_byte, // Byte received 33 | output is_receiving, // Low when receive line is idle. 34 | output is_transmitting, // Low when transmit line is idle. 35 | output recv_error // Indicates error in receiving packet. 36 | ); 37 | 38 | // parameter CLOCK_DIVIDE = 1302; // clock rate (50Mhz) / (baud rate (9600) * 4) 39 | // parameter CLOCK_DIVIDE = 109; // clock rate (50Mhz) / (baud rate (115200) * 4) 40 | parameter CLOCK_DIVIDE = 217; // clock rate (100Mhz) / (baud rate (115200) * 4) 41 | 42 | // States for the receiving state machine. 43 | // These are just constants, not parameters to override. 44 | parameter RX_IDLE = 0; 45 | parameter RX_CHECK_START = 1; 46 | parameter RX_READ_BITS = 2; 47 | parameter RX_CHECK_STOP = 3; 48 | parameter RX_DELAY_RESTART = 4; 49 | parameter RX_ERROR = 5; 50 | parameter RX_RECEIVED = 6; 51 | 52 | // States for the transmitting state machine. 53 | // Constants - do not override. 54 | parameter TX_IDLE = 0; 55 | parameter TX_SENDING = 1; 56 | parameter TX_DELAY_RESTART = 2; 57 | 58 | reg [10:0] rx_clk_divider = CLOCK_DIVIDE; 59 | reg [10:0] tx_clk_divider = CLOCK_DIVIDE; 60 | 61 | reg [2:0] recv_state = RX_IDLE; 62 | reg [5:0] rx_countdown; 63 | reg [3:0] rx_bits_remaining; 64 | reg [7:0] rx_data; 65 | 66 | reg tx_out = 1'b1; 67 | reg [1:0] tx_state = TX_IDLE; 68 | reg [5:0] tx_countdown; 69 | reg [3:0] tx_bits_remaining; 70 | reg [7:0] tx_data; 71 | 72 | assign received = recv_state == RX_RECEIVED; 73 | assign recv_error = recv_state == RX_ERROR; 74 | assign is_receiving = recv_state != RX_IDLE; 75 | assign rx_byte = rx_data; 76 | 77 | assign tx = tx_out; 78 | assign is_transmitting = tx_state != TX_IDLE; 79 | 80 | always @(posedge clk) begin 81 | if (rst) begin 82 | recv_state = RX_IDLE; 83 | tx_state = TX_IDLE; 84 | end 85 | 86 | // The clk_divider counter counts down from 87 | // the CLOCK_DIVIDE constant. Whenever it 88 | // reaches 0, 1/16 of the bit period has elapsed. 89 | // Countdown timers for the receiving and transmitting 90 | // state machines are decremented. 91 | rx_clk_divider = rx_clk_divider - 1; 92 | if (!rx_clk_divider) begin 93 | rx_clk_divider = CLOCK_DIVIDE; 94 | rx_countdown = rx_countdown - 1; 95 | end 96 | tx_clk_divider = tx_clk_divider - 1; 97 | if (!tx_clk_divider) begin 98 | tx_clk_divider = CLOCK_DIVIDE; 99 | tx_countdown = tx_countdown - 1; 100 | end 101 | 102 | // Receive state machine 103 | case (recv_state) 104 | RX_IDLE: begin 105 | // A low pulse on the receive line indicates the 106 | // start of data. 107 | if (!rx) begin 108 | // Wait half the period - should resume in the 109 | // middle of this first pulse. 110 | rx_clk_divider = CLOCK_DIVIDE; 111 | rx_countdown = 2; 112 | recv_state = RX_CHECK_START; 113 | end 114 | end 115 | RX_CHECK_START: begin 116 | if (!rx_countdown) begin 117 | // Check the pulse is still there 118 | if (!rx) begin 119 | // Pulse still there - good 120 | // Wait the bit period to resume half-way 121 | // through the first bit. 122 | rx_countdown = 4; 123 | rx_bits_remaining = 8; 124 | recv_state = RX_READ_BITS; 125 | end else begin 126 | // Pulse lasted less than half the period - 127 | // not a valid transmission. 128 | recv_state = RX_ERROR; 129 | end 130 | end 131 | end 132 | RX_READ_BITS: begin 133 | if (!rx_countdown) begin 134 | // Should be half-way through a bit pulse here. 135 | // Read this bit in, wait for the next if we 136 | // have more to get. 137 | rx_data = {rx, rx_data[7:1]}; 138 | rx_countdown = 4; 139 | rx_bits_remaining = rx_bits_remaining - 1; 140 | recv_state = rx_bits_remaining ? RX_READ_BITS : RX_CHECK_STOP; 141 | end 142 | end 143 | RX_CHECK_STOP: begin 144 | if (!rx_countdown) begin 145 | // Should resume half-way through the stop bit 146 | // This should be high - if not, reject the 147 | // transmission and signal an error. 148 | recv_state = rx ? RX_RECEIVED : RX_ERROR; 149 | end 150 | end 151 | RX_DELAY_RESTART: begin 152 | // Waits a set number of cycles before accepting 153 | // another transmission. 154 | recv_state = rx_countdown ? RX_DELAY_RESTART : RX_IDLE; 155 | end 156 | RX_ERROR: begin 157 | // There was an error receiving. 158 | // Raises the recv_error flag for one clock 159 | // cycle while in this state and then waits 160 | // 2 bit periods before accepting another 161 | // transmission. 162 | rx_countdown = 8; 163 | recv_state = RX_DELAY_RESTART; 164 | end 165 | RX_RECEIVED: begin 166 | // Successfully received a byte. 167 | // Raises the received flag for one clock 168 | // cycle while in this state. 169 | recv_state = RX_IDLE; 170 | end 171 | endcase 172 | 173 | // Transmit state machine 174 | case (tx_state) 175 | TX_IDLE: begin 176 | if (transmit) begin 177 | // If the transmit flag is raised in the idle 178 | // state, start transmitting the current content 179 | // of the tx_byte input. 180 | tx_data = tx_byte; 181 | // Send the initial, low pulse of 1 bit period 182 | // to signal the start, followed by the data 183 | tx_clk_divider = CLOCK_DIVIDE; 184 | tx_countdown = 4; 185 | tx_out = 0; 186 | tx_bits_remaining = 8; 187 | tx_state = TX_SENDING; 188 | end 189 | end 190 | TX_SENDING: begin 191 | if (!tx_countdown) begin 192 | if (tx_bits_remaining) begin 193 | tx_bits_remaining = tx_bits_remaining - 1; 194 | tx_out = tx_data[0]; 195 | tx_data = {1'b0, tx_data[7:1]}; 196 | tx_countdown = 4; 197 | tx_state = TX_SENDING; 198 | end else begin 199 | // Set delay to send out 2 stop bits. 200 | tx_out = 1; 201 | tx_countdown = 8; 202 | tx_state = TX_DELAY_RESTART; 203 | end 204 | end 205 | end 206 | TX_DELAY_RESTART: begin 207 | // Wait until tx_countdown reaches the end before 208 | // we send another transmission. This covers the 209 | // "stop bit" delay. 210 | tx_state = tx_countdown ? TX_DELAY_RESTART : TX_IDLE; 211 | end 212 | endcase 213 | end 214 | 215 | endmodule 216 | -------------------------------------------------------------------------------- /behavioral/wb_uart/uart_tfifo.v: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | //// //// 3 | //// uart_tfifo.v //// 4 | //// //// 5 | //// //// 6 | //// This file is part of the "UART 16550 compatible" project //// 7 | //// http://www.opencores.org/cores/uart16550/ //// 8 | //// //// 9 | //// Documentation related to this project: //// 10 | //// - http://www.opencores.org/cores/uart16550/ //// 11 | //// //// 12 | //// Projects compatibility: //// 13 | //// - WISHBONE //// 14 | //// RS232 Protocol //// 15 | //// 16550D uart (mostly supported) //// 16 | //// //// 17 | //// Overview (main Features): //// 18 | //// UART core transmitter FIFO //// 19 | //// //// 20 | //// To Do: //// 21 | //// Nothing. //// 22 | //// //// 23 | //// Author(s): //// 24 | //// - gorban@opencores.org //// 25 | //// - Jacob Gorban //// 26 | //// - Igor Mohor (igorm@opencores.org) //// 27 | //// //// 28 | //// Created: 2001/05/12 //// 29 | //// Last Updated: 2002/07/22 //// 30 | //// (See log for the revision history) //// 31 | //// //// 32 | //// //// 33 | ////////////////////////////////////////////////////////////////////// 34 | //// //// 35 | //// Copyright (C) 2000, 2001 Authors //// 36 | //// //// 37 | //// This source file may be used and distributed without //// 38 | //// restriction provided that this copyright statement is not //// 39 | //// removed from the file and that any derivative work contains //// 40 | //// the original copyright notice and the associated disclaimer. //// 41 | //// //// 42 | //// This source file is free software; you can redistribute it //// 43 | //// and/or modify it under the terms of the GNU Lesser General //// 44 | //// Public License as published by the Free Software Foundation; //// 45 | //// either version 2.1 of the License, or (at your option) any //// 46 | //// later version. //// 47 | //// //// 48 | //// This source is distributed in the hope that it will be //// 49 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// 50 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// 51 | //// PURPOSE. See the GNU Lesser General Public License for more //// 52 | //// details. //// 53 | //// //// 54 | //// You should have received a copy of the GNU Lesser General //// 55 | //// Public License along with this source; if not, download it //// 56 | //// from http://www.opencores.org/lgpl.shtml //// 57 | //// //// 58 | ////////////////////////////////////////////////////////////////////// 59 | // 60 | // CVS Revision History 61 | // 62 | // $Log: uart_tfifo.v.rca $ 63 | // 64 | // Revision: 1.1.1.1 Tue Jun 7 09:39:01 2011 copew1 65 | // first stab at merging s0903a branch. 66 | // 67 | // Revision: 1.1 Fri Jun 3 12:44:14 2011 tractp1 68 | // UART in test bench to send/receive ASCII bytes with FPGA UART and 69 | // command processing task in firmware 70 | // Revision 1.1 2002/07/22 23:02:23 gorban 71 | // Bug Fixes: 72 | // * Possible loss of sync and bad reception of stop bit on slow baud rates fixed. 73 | // Problem reported by Kenny.Tung. 74 | // * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers. 75 | // 76 | // Improvements: 77 | // * Made FIFO's as general inferrable memory where possible. 78 | // So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx). 79 | // This saves about 1/3 of the Slice count and reduces P&R and synthesis times. 80 | // 81 | // * Added optional baudrate output (baud_o). 82 | // This is identical to BAUDOUT* signal on 16550 chip. 83 | // It outputs 16xbit_clock_rate - the divided clock. 84 | // It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use. 85 | // 86 | // Revision 1.16 2001/12/20 13:25:46 mohor 87 | // rx push changed to be only one cycle wide. 88 | // 89 | // Revision 1.15 2001/12/18 09:01:07 mohor 90 | // Bug that was entered in the last update fixed (rx state machine). 91 | // 92 | // Revision 1.14 2001/12/17 14:46:48 mohor 93 | // overrun signal was moved to separate block because many sequential lsr 94 | // reads were preventing data from being written to rx fifo. 95 | // underrun signal was not used and was removed from the project. 96 | // 97 | // Revision 1.13 2001/11/26 21:38:54 gorban 98 | // Lots of fixes: 99 | // Break condition wasn't handled correctly at all. 100 | // LSR bits could lose their values. 101 | // LSR value after reset was wrong. 102 | // Timing of THRE interrupt signal corrected. 103 | // LSR bit 0 timing corrected. 104 | // 105 | // Revision 1.12 2001/11/08 14:54:23 mohor 106 | // Comments in Slovene language deleted, few small fixes for better work of 107 | // old tools. IRQs need to be fix. 108 | // 109 | // Revision 1.11 2001/11/07 17:51:52 gorban 110 | // Heavily rewritten interrupt and LSR subsystems. 111 | // Many bugs hopefully squashed. 112 | // 113 | // Revision 1.10 2001/10/20 09:58:40 gorban 114 | // Small synopsis fixes 115 | // 116 | // Revision 1.9 2001/08/24 21:01:12 mohor 117 | // Things connected to parity changed. 118 | // Clock devider changed. 119 | // 120 | // Revision 1.8 2001/08/24 08:48:10 mohor 121 | // FIFO was not cleared after the data was read bug fixed. 122 | // 123 | // Revision 1.7 2001/08/23 16:05:05 mohor 124 | // Stop bit bug fixed. 125 | // Parity bug fixed. 126 | // WISHBONE read cycle bug fixed, 127 | // OE indicator (Overrun Error) bug fixed. 128 | // PE indicator (Parity Error) bug fixed. 129 | // Register read bug fixed. 130 | // 131 | // Revision 1.3 2001/05/31 20:08:01 gorban 132 | // FIFO changes and other corrections. 133 | // 134 | // Revision 1.3 2001/05/27 17:37:48 gorban 135 | // Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file. 136 | // 137 | // Revision 1.2 2001/05/17 18:34:18 gorban 138 | // First 'stable' release. Should be sythesizable now. Also added new header. 139 | // 140 | // Revision 1.0 2001-05-17 21:27:12+02 jacob 141 | // Initial revision 142 | // 143 | // 144 | 145 | // synopsys translate_off 146 | `include "timescale.v" 147 | // synopsys translate_on 148 | 149 | `include "uart_defines.v" 150 | 151 | module uart_tfifo (clk, 152 | wb_rst_i, data_in, data_out, 153 | // Control signals 154 | push, // push strobe, active high 155 | pop, // pop strobe, active high 156 | // status signals 157 | overrun, 158 | count, 159 | fifo_reset, 160 | reset_status 161 | ); 162 | 163 | 164 | // FIFO parameters 165 | parameter fifo_width = `UART_FIFO_WIDTH; 166 | parameter fifo_depth = `UART_FIFO_DEPTH; 167 | parameter fifo_pointer_w = `UART_FIFO_POINTER_W; 168 | parameter fifo_counter_w = `UART_FIFO_COUNTER_W; 169 | 170 | input clk; 171 | input wb_rst_i; 172 | input push; 173 | input pop; 174 | input [fifo_width-1:0] data_in; 175 | input fifo_reset; 176 | input reset_status; 177 | 178 | output [fifo_width-1:0] data_out; 179 | output overrun; 180 | output [fifo_counter_w-1:0] count; 181 | 182 | wire [fifo_width-1:0] data_out; 183 | 184 | // FIFO pointers 185 | reg [fifo_pointer_w-1:0] top; 186 | reg [fifo_pointer_w-1:0] bottom; 187 | 188 | reg [fifo_counter_w-1:0] count; 189 | reg overrun; 190 | wire [fifo_pointer_w-1:0] top_plus_1 = top + 1'b1; 191 | 192 | raminfr #(fifo_pointer_w,fifo_width,fifo_depth) tfifo 193 | (.clk(clk), 194 | .we(push), 195 | .a(top), 196 | .dpra(bottom), 197 | .di(data_in), 198 | .dpo(data_out) 199 | ); 200 | 201 | 202 | always @(posedge clk or posedge wb_rst_i) // synchronous FIFO 203 | begin 204 | if (wb_rst_i) 205 | begin 206 | top <= #1 0; 207 | bottom <= #1 1'b0; 208 | count <= #1 0; 209 | end 210 | else 211 | if (fifo_reset) begin 212 | top <= #1 0; 213 | bottom <= #1 1'b0; 214 | count <= #1 0; 215 | end 216 | else 217 | begin 218 | case ({push, pop}) 219 | 2'b10 : if (count0) 225 | begin 226 | bottom <= #1 bottom + 1'b1; 227 | count <= #1 count - 1'b1; 228 | end 229 | 2'b11 : begin 230 | bottom <= #1 bottom + 1'b1; 231 | top <= #1 top_plus_1; 232 | end 233 | default: ; 234 | endcase 235 | end 236 | end // always 237 | 238 | always @(posedge clk or posedge wb_rst_i) // synchronous FIFO 239 | begin 240 | if (wb_rst_i) 241 | overrun <= #1 1'b0; 242 | else 243 | if(fifo_reset | reset_status) 244 | overrun <= #1 1'b0; 245 | else 246 | if(push & (count==fifo_depth)) 247 | overrun <= #1 1'b1; 248 | end // always 249 | 250 | endmodule 251 | -------------------------------------------------------------------------------- /behavioral/wb_uart/uart_defines.v: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | //// //// 3 | //// uart_defines.v //// 4 | //// //// 5 | //// //// 6 | //// This file is part of the "UART 16550 compatible" project //// 7 | //// http://www.opencores.org/cores/uart16550/ //// 8 | //// //// 9 | //// Documentation related to this project: //// 10 | //// - http://www.opencores.org/cores/uart16550/ //// 11 | //// //// 12 | //// Projects compatibility: //// 13 | //// - WISHBONE //// 14 | //// RS232 Protocol //// 15 | //// 16550D uart (mostly supported) //// 16 | //// //// 17 | //// Overview (main Features): //// 18 | //// Defines of the Core //// 19 | //// //// 20 | //// Known problems (limits): //// 21 | //// None //// 22 | //// //// 23 | //// To Do: //// 24 | //// Nothing. //// 25 | //// //// 26 | //// Author(s): //// 27 | //// - gorban@opencores.org //// 28 | //// - Jacob Gorban //// 29 | //// - Igor Mohor (igorm@opencores.org) //// 30 | //// //// 31 | //// Created: 2001/05/12 //// 32 | //// Last Updated: 2001/05/17 //// 33 | //// (See log for the revision history) //// 34 | //// //// 35 | //// //// 36 | ////////////////////////////////////////////////////////////////////// 37 | //// //// 38 | //// Copyright (C) 2000, 2001 Authors //// 39 | //// //// 40 | //// This source file may be used and distributed without //// 41 | //// restriction provided that this copyright statement is not //// 42 | //// removed from the file and that any derivative work contains //// 43 | //// the original copyright notice and the associated disclaimer. //// 44 | //// //// 45 | //// This source file is free software; you can redistribute it //// 46 | //// and/or modify it under the terms of the GNU Lesser General //// 47 | //// Public License as published by the Free Software Foundation; //// 48 | //// either version 2.1 of the License, or (at your option) any //// 49 | //// later version. //// 50 | //// //// 51 | //// This source is distributed in the hope that it will be //// 52 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// 53 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// 54 | //// PURPOSE. See the GNU Lesser General Public License for more //// 55 | //// details. //// 56 | //// //// 57 | //// You should have received a copy of the GNU Lesser General //// 58 | //// Public License along with this source; if not, download it //// 59 | //// from http://www.opencores.org/lgpl.shtml //// 60 | //// //// 61 | ////////////////////////////////////////////////////////////////////// 62 | // 63 | // CVS Revision History 64 | // 65 | // $Log: uart_defines.v.rca $ 66 | // 67 | // Revision: 1.1.1.1 Tue Jun 7 09:39:01 2011 copew1 68 | // first stab at merging s0903a branch. 69 | // 70 | // Revision: 1.1 Fri Jun 3 12:44:15 2011 tractp1 71 | // UART in test bench to send/receive ASCII bytes with FPGA UART and 72 | // command processing task in firmware 73 | // Revision 1.13 2003/06/11 16:37:47 gorban 74 | // This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended. 75 | // 76 | // Revision 1.12 2002/07/22 23:02:23 gorban 77 | // Bug Fixes: 78 | // * Possible loss of sync and bad reception of stop bit on slow baud rates fixed. 79 | // Problem reported by Kenny.Tung. 80 | // * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers. 81 | // 82 | // Improvements: 83 | // * Made FIFO's as general inferrable memory where possible. 84 | // So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx). 85 | // This saves about 1/3 of the Slice count and reduces P&R and synthesis times. 86 | // 87 | // * Added optional baudrate output (baud_o). 88 | // This is identical to BAUDOUT* signal on 16550 chip. 89 | // It outputs 16xbit_clock_rate - the divided clock. 90 | // It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use. 91 | // 92 | // Revision 1.10 2001/12/11 08:55:40 mohor 93 | // Scratch register define added. 94 | // 95 | // Revision 1.9 2001/12/03 21:44:29 gorban 96 | // Updated specification documentation. 97 | // Added full 32-bit data bus interface, now as default. 98 | // Address is 5-bit wide in 32-bit data bus mode. 99 | // Added wb_sel_i input to the core. It's used in the 32-bit mode. 100 | // Added debug interface with two 32-bit read-only registers in 32-bit mode. 101 | // Bits 5 and 6 of LSR are now only cleared on TX FIFO write. 102 | // My small test bench is modified to work with 32-bit mode. 103 | // 104 | // Revision 1.8 2001/11/26 21:38:54 gorban 105 | // Lots of fixes: 106 | // Break condition wasn't handled correctly at all. 107 | // LSR bits could lose their values. 108 | // LSR value after reset was wrong. 109 | // Timing of THRE interrupt signal corrected. 110 | // LSR bit 0 timing corrected. 111 | // 112 | // Revision 1.7 2001/08/24 21:01:12 mohor 113 | // Things connected to parity changed. 114 | // Clock devider changed. 115 | // 116 | // Revision 1.6 2001/08/23 16:05:05 mohor 117 | // Stop bit bug fixed. 118 | // Parity bug fixed. 119 | // WISHBONE read cycle bug fixed, 120 | // OE indicator (Overrun Error) bug fixed. 121 | // PE indicator (Parity Error) bug fixed. 122 | // Register read bug fixed. 123 | // 124 | // Revision 1.5 2001/05/31 20:08:01 gorban 125 | // FIFO changes and other corrections. 126 | // 127 | // Revision 1.4 2001/05/21 19:12:02 gorban 128 | // Corrected some Linter messages. 129 | // 130 | // Revision 1.3 2001/05/17 18:34:18 gorban 131 | // First 'stable' release. Should be sythesizable now. Also added new header. 132 | // 133 | // Revision 1.0 2001-05-17 21:27:11+02 jacob 134 | // Initial revision 135 | // 136 | // 137 | 138 | // remove comments to restore to use the new version with 8 data bit interface 139 | // in 32bit-bus mode, the wb_sel_i signal is used to put data in correct place 140 | // also, in 8-bit version there'll be no debugging features included 141 | // CAUTION: doesn't work with current version of OR1200 142 | //`define DATA_BUS_WIDTH_8 143 | 144 | `ifdef DATA_BUS_WIDTH_8 145 | `define UART_ADDR_WIDTH 3 146 | `define UART_DATA_WIDTH 8 147 | `else 148 | `define UART_ADDR_WIDTH 5 149 | `define UART_DATA_WIDTH 32 150 | `endif 151 | 152 | // Uncomment this if you want your UART to have 153 | // 16xBaudrate output port. 154 | // If defined, the enable signal will be used to drive baudrate_o signal 155 | // It's frequency is 16xbaudrate 156 | 157 | `define UART_HAS_BAUDRATE_OUTPUT 158 | 159 | // Register addresses 160 | `define UART_REG_RB `UART_ADDR_WIDTH'd0 // receiver buffer 161 | `define UART_REG_TR `UART_ADDR_WIDTH'd0 // transmitter 162 | `define UART_REG_IE `UART_ADDR_WIDTH'd1 // Interrupt enable 163 | `define UART_REG_II `UART_ADDR_WIDTH'd2 // Interrupt identification 164 | `define UART_REG_FC `UART_ADDR_WIDTH'd2 // FIFO control 165 | `define UART_REG_LC `UART_ADDR_WIDTH'd3 // Line Control 166 | `define UART_REG_MC `UART_ADDR_WIDTH'd4 // Modem control 167 | `define UART_REG_LS `UART_ADDR_WIDTH'd5 // Line status 168 | `define UART_REG_MS `UART_ADDR_WIDTH'd6 // Modem status 169 | `define UART_REG_SR `UART_ADDR_WIDTH'd7 // Scratch register 170 | `define UART_REG_DL1 `UART_ADDR_WIDTH'd0 // Divisor latch bytes (1-2) 171 | `define UART_REG_DL2 `UART_ADDR_WIDTH'd1 172 | 173 | // Interrupt Enable register bits 174 | `define UART_IE_RDA 0 // Received Data available interrupt 175 | `define UART_IE_THRE 1 // Transmitter Holding Register empty interrupt 176 | `define UART_IE_RLS 2 // Receiver Line Status Interrupt 177 | `define UART_IE_MS 3 // Modem Status Interrupt 178 | 179 | // Interrupt Identification register bits 180 | `define UART_II_IP 0 // Interrupt pending when 0 181 | `define UART_II_II 3:1 // Interrupt identification 182 | 183 | // Interrupt identification values for bits 3:1 184 | `define UART_II_RLS 3'b011 // Receiver Line Status 185 | `define UART_II_RDA 3'b010 // Receiver Data available 186 | `define UART_II_TI 3'b110 // Timeout Indication 187 | `define UART_II_THRE 3'b001 // Transmitter Holding Register empty 188 | `define UART_II_MS 3'b000 // Modem Status 189 | 190 | // FIFO Control Register bits 191 | `define UART_FC_TL 1:0 // Trigger level 192 | 193 | // FIFO trigger level values 194 | `define UART_FC_1 2'b00 195 | `define UART_FC_4 2'b01 196 | `define UART_FC_8 2'b10 197 | `define UART_FC_14 2'b11 198 | 199 | // Line Control register bits 200 | `define UART_LC_BITS 1:0 // bits in character 201 | `define UART_LC_SB 2 // stop bits 202 | `define UART_LC_PE 3 // parity enable 203 | `define UART_LC_EP 4 // even parity 204 | `define UART_LC_SP 5 // stick parity 205 | `define UART_LC_BC 6 // Break control 206 | `define UART_LC_DL 7 // Divisor Latch access bit 207 | 208 | // Modem Control register bits 209 | `define UART_MC_DTR 0 210 | `define UART_MC_RTS 1 211 | `define UART_MC_OUT1 2 212 | `define UART_MC_OUT2 3 213 | `define UART_MC_LB 4 // Loopback mode 214 | 215 | // Line Status Register bits 216 | `define UART_LS_DR 0 // Data ready 217 | `define UART_LS_OE 1 // Overrun Error 218 | `define UART_LS_PE 2 // Parity Error 219 | `define UART_LS_FE 3 // Framing Error 220 | `define UART_LS_BI 4 // Break interrupt 221 | `define UART_LS_TFE 5 // Transmit FIFO is empty 222 | `define UART_LS_TE 6 // Transmitter Empty indicator 223 | `define UART_LS_EI 7 // Error indicator 224 | 225 | // Modem Status Register bits 226 | `define UART_MS_DCTS 0 // Delta signals 227 | `define UART_MS_DDSR 1 228 | `define UART_MS_TERI 2 229 | `define UART_MS_DDCD 3 230 | `define UART_MS_CCTS 4 // Complement signals 231 | `define UART_MS_CDSR 5 232 | `define UART_MS_CRI 6 233 | `define UART_MS_CDCD 7 234 | 235 | // FIFO parameter defines 236 | 237 | `define UART_FIFO_WIDTH 8 238 | `define UART_FIFO_DEPTH 16 239 | `define UART_FIFO_POINTER_W 4 240 | `define UART_FIFO_COUNTER_W 5 241 | // receiver fifo has width 11 because it has break, parity and framing error bits 242 | `define UART_FIFO_REC_WIDTH 11 243 | 244 | 245 | `define VERBOSE_WB 0 // All activity on the WISHBONE is recorded 246 | `define VERBOSE_LINE_STATUS 0 // Details about the lsr (line status register) 247 | `define FAST_TEST 1 // 64/1024 packets are sent 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | -------------------------------------------------------------------------------- /behavioral/wb_uart/uart_rfifo.v: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | //// //// 3 | //// uart_rfifo.v (Modified from uart_fifo.v) //// 4 | //// //// 5 | //// //// 6 | //// This file is part of the "UART 16550 compatible" project //// 7 | //// http://www.opencores.org/cores/uart16550/ //// 8 | //// //// 9 | //// Documentation related to this project: //// 10 | //// - http://www.opencores.org/cores/uart16550/ //// 11 | //// //// 12 | //// Projects compatibility: //// 13 | //// - WISHBONE //// 14 | //// RS232 Protocol //// 15 | //// 16550D uart (mostly supported) //// 16 | //// //// 17 | //// Overview (main Features): //// 18 | //// UART core receiver FIFO //// 19 | //// //// 20 | //// To Do: //// 21 | //// Nothing. //// 22 | //// //// 23 | //// Author(s): //// 24 | //// - gorban@opencores.org //// 25 | //// - Jacob Gorban //// 26 | //// - Igor Mohor (igorm@opencores.org) //// 27 | //// //// 28 | //// Created: 2001/05/12 //// 29 | //// Last Updated: 2002/07/22 //// 30 | //// (See log for the revision history) //// 31 | //// //// 32 | //// //// 33 | ////////////////////////////////////////////////////////////////////// 34 | //// //// 35 | //// Copyright (C) 2000, 2001 Authors //// 36 | //// //// 37 | //// This source file may be used and distributed without //// 38 | //// restriction provided that this copyright statement is not //// 39 | //// removed from the file and that any derivative work contains //// 40 | //// the original copyright notice and the associated disclaimer. //// 41 | //// //// 42 | //// This source file is free software; you can redistribute it //// 43 | //// and/or modify it under the terms of the GNU Lesser General //// 44 | //// Public License as published by the Free Software Foundation; //// 45 | //// either version 2.1 of the License, or (at your option) any //// 46 | //// later version. //// 47 | //// //// 48 | //// This source is distributed in the hope that it will be //// 49 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// 50 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// 51 | //// PURPOSE. See the GNU Lesser General Public License for more //// 52 | //// details. //// 53 | //// //// 54 | //// You should have received a copy of the GNU Lesser General //// 55 | //// Public License along with this source; if not, download it //// 56 | //// from http://www.opencores.org/lgpl.shtml //// 57 | //// //// 58 | ////////////////////////////////////////////////////////////////////// 59 | // 60 | // CVS Revision History 61 | // 62 | // $Log: uart_rfifo.v.rca $ 63 | // 64 | // Revision: 1.1.1.1 Tue Jun 7 09:39:01 2011 copew1 65 | // first stab at merging s0903a branch. 66 | // 67 | // Revision: 1.1 Fri Jun 3 12:44:13 2011 tractp1 68 | // UART in test bench to send/receive ASCII bytes with FPGA UART and 69 | // command processing task in firmware 70 | // Revision 1.3 2003/06/11 16:37:47 gorban 71 | // This fixes errors in some cases when data is being read and put to the FIFO at the same time. Patch is submitted by Scott Furman. Update is very recommended. 72 | // 73 | // Revision 1.2 2002/07/29 21:16:18 gorban 74 | // The uart_defines.v file is included again in sources. 75 | // 76 | // Revision 1.1 2002/07/22 23:02:23 gorban 77 | // Bug Fixes: 78 | // * Possible loss of sync and bad reception of stop bit on slow baud rates fixed. 79 | // Problem reported by Kenny.Tung. 80 | // * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers. 81 | // 82 | // Improvements: 83 | // * Made FIFO's as general inferrable memory where possible. 84 | // So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx). 85 | // This saves about 1/3 of the Slice count and reduces P&R and synthesis times. 86 | // 87 | // * Added optional baudrate output (baud_o). 88 | // This is identical to BAUDOUT* signal on 16550 chip. 89 | // It outputs 16xbit_clock_rate - the divided clock. 90 | // It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use. 91 | // 92 | // Revision 1.16 2001/12/20 13:25:46 mohor 93 | // rx push changed to be only one cycle wide. 94 | // 95 | // Revision 1.15 2001/12/18 09:01:07 mohor 96 | // Bug that was entered in the last update fixed (rx state machine). 97 | // 98 | // Revision 1.14 2001/12/17 14:46:48 mohor 99 | // overrun signal was moved to separate block because many sequential lsr 100 | // reads were preventing data from being written to rx fifo. 101 | // underrun signal was not used and was removed from the project. 102 | // 103 | // Revision 1.13 2001/11/26 21:38:54 gorban 104 | // Lots of fixes: 105 | // Break condition wasn't handled correctly at all. 106 | // LSR bits could lose their values. 107 | // LSR value after reset was wrong. 108 | // Timing of THRE interrupt signal corrected. 109 | // LSR bit 0 timing corrected. 110 | // 111 | // Revision 1.12 2001/11/08 14:54:23 mohor 112 | // Comments in Slovene language deleted, few small fixes for better work of 113 | // old tools. IRQs need to be fix. 114 | // 115 | // Revision 1.11 2001/11/07 17:51:52 gorban 116 | // Heavily rewritten interrupt and LSR subsystems. 117 | // Many bugs hopefully squashed. 118 | // 119 | // Revision 1.10 2001/10/20 09:58:40 gorban 120 | // Small synopsis fixes 121 | // 122 | // Revision 1.9 2001/08/24 21:01:12 mohor 123 | // Things connected to parity changed. 124 | // Clock devider changed. 125 | // 126 | // Revision 1.8 2001/08/24 08:48:10 mohor 127 | // FIFO was not cleared after the data was read bug fixed. 128 | // 129 | // Revision 1.7 2001/08/23 16:05:05 mohor 130 | // Stop bit bug fixed. 131 | // Parity bug fixed. 132 | // WISHBONE read cycle bug fixed, 133 | // OE indicator (Overrun Error) bug fixed. 134 | // PE indicator (Parity Error) bug fixed. 135 | // Register read bug fixed. 136 | // 137 | // Revision 1.3 2001/05/31 20:08:01 gorban 138 | // FIFO changes and other corrections. 139 | // 140 | // Revision 1.3 2001/05/27 17:37:48 gorban 141 | // Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file. 142 | // 143 | // Revision 1.2 2001/05/17 18:34:18 gorban 144 | // First 'stable' release. Should be sythesizable now. Also added new header. 145 | // 146 | // Revision 1.0 2001-05-17 21:27:12+02 jacob 147 | // Initial revision 148 | // 149 | // 150 | 151 | // synopsys translate_off 152 | `include "timescale.v" 153 | // synopsys translate_on 154 | 155 | `include "uart_defines.v" 156 | 157 | module uart_rfifo (clk, 158 | wb_rst_i, data_in, data_out, 159 | // Control signals 160 | push, // push strobe, active high 161 | pop, // pop strobe, active high 162 | // status signals 163 | overrun, 164 | count, 165 | error_bit, 166 | fifo_reset, 167 | reset_status 168 | ); 169 | 170 | 171 | // FIFO parameters 172 | parameter fifo_width = `UART_FIFO_WIDTH; 173 | parameter fifo_depth = `UART_FIFO_DEPTH; 174 | parameter fifo_pointer_w = `UART_FIFO_POINTER_W; 175 | parameter fifo_counter_w = `UART_FIFO_COUNTER_W; 176 | 177 | input clk; 178 | input wb_rst_i; 179 | input push; 180 | input pop; 181 | input [fifo_width-1:0] data_in; 182 | input fifo_reset; 183 | input reset_status; 184 | 185 | output [fifo_width-1:0] data_out; 186 | output overrun; 187 | output [fifo_counter_w-1:0] count; 188 | output error_bit; 189 | 190 | wire [fifo_width-1:0] data_out; 191 | wire [7:0] data8_out; 192 | // flags FIFO 193 | reg [2:0] fifo[fifo_depth-1:0]; 194 | 195 | // FIFO pointers 196 | reg [fifo_pointer_w-1:0] top; 197 | reg [fifo_pointer_w-1:0] bottom; 198 | 199 | reg [fifo_counter_w-1:0] count; 200 | reg overrun; 201 | 202 | wire [fifo_pointer_w-1:0] top_plus_1 = top + 1'b1; 203 | 204 | raminfr #(fifo_pointer_w,8,fifo_depth) rfifo 205 | (.clk(clk), 206 | .we(push), 207 | .a(top), 208 | .dpra(bottom), 209 | .di(data_in[fifo_width-1:fifo_width-8]), 210 | .dpo(data8_out) 211 | ); 212 | 213 | always @(posedge clk or posedge wb_rst_i) // synchronous FIFO 214 | begin 215 | if (wb_rst_i) 216 | begin 217 | top <= #1 0; 218 | bottom <= #1 1'b0; 219 | count <= #1 0; 220 | fifo[0] <= #1 0; 221 | fifo[1] <= #1 0; 222 | fifo[2] <= #1 0; 223 | fifo[3] <= #1 0; 224 | fifo[4] <= #1 0; 225 | fifo[5] <= #1 0; 226 | fifo[6] <= #1 0; 227 | fifo[7] <= #1 0; 228 | fifo[8] <= #1 0; 229 | fifo[9] <= #1 0; 230 | fifo[10] <= #1 0; 231 | fifo[11] <= #1 0; 232 | fifo[12] <= #1 0; 233 | fifo[13] <= #1 0; 234 | fifo[14] <= #1 0; 235 | fifo[15] <= #1 0; 236 | end 237 | else 238 | if (fifo_reset) begin 239 | top <= #1 0; 240 | bottom <= #1 1'b0; 241 | count <= #1 0; 242 | fifo[0] <= #1 0; 243 | fifo[1] <= #1 0; 244 | fifo[2] <= #1 0; 245 | fifo[3] <= #1 0; 246 | fifo[4] <= #1 0; 247 | fifo[5] <= #1 0; 248 | fifo[6] <= #1 0; 249 | fifo[7] <= #1 0; 250 | fifo[8] <= #1 0; 251 | fifo[9] <= #1 0; 252 | fifo[10] <= #1 0; 253 | fifo[11] <= #1 0; 254 | fifo[12] <= #1 0; 255 | fifo[13] <= #1 0; 256 | fifo[14] <= #1 0; 257 | fifo[15] <= #1 0; 258 | end 259 | else 260 | begin 261 | case ({push, pop}) 262 | 2'b10 : if (count0) 269 | begin 270 | fifo[bottom] <= #1 0; 271 | bottom <= #1 bottom + 1'b1; 272 | count <= #1 count - 1'b1; 273 | end 274 | 2'b11 : begin 275 | bottom <= #1 bottom + 1'b1; 276 | top <= #1 top_plus_1; 277 | fifo[top] <= #1 data_in[2:0]; 278 | end 279 | default: ; 280 | endcase 281 | end 282 | end // always 283 | 284 | always @(posedge clk or posedge wb_rst_i) // synchronous FIFO 285 | begin 286 | if (wb_rst_i) 287 | overrun <= #1 1'b0; 288 | else 289 | if(fifo_reset | reset_status) 290 | overrun <= #1 1'b0; 291 | else 292 | if(push & ~pop & (count==fifo_depth)) 293 | overrun <= #1 1'b1; 294 | end // always 295 | 296 | 297 | // please note though that data_out is only valid one clock after pop signal 298 | assign data_out = {data8_out,fifo[bottom]}; 299 | 300 | // Additional logic for detection of error conditions (parity and framing) inside the FIFO 301 | // for the Line Status Register bit 7 302 | 303 | wire [2:0] word0 = fifo[0]; 304 | wire [2:0] word1 = fifo[1]; 305 | wire [2:0] word2 = fifo[2]; 306 | wire [2:0] word3 = fifo[3]; 307 | wire [2:0] word4 = fifo[4]; 308 | wire [2:0] word5 = fifo[5]; 309 | wire [2:0] word6 = fifo[6]; 310 | wire [2:0] word7 = fifo[7]; 311 | 312 | wire [2:0] word8 = fifo[8]; 313 | wire [2:0] word9 = fifo[9]; 314 | wire [2:0] word10 = fifo[10]; 315 | wire [2:0] word11 = fifo[11]; 316 | wire [2:0] word12 = fifo[12]; 317 | wire [2:0] word13 = fifo[13]; 318 | wire [2:0] word14 = fifo[14]; 319 | wire [2:0] word15 = fifo[15]; 320 | 321 | // a 1 is returned if any of the error bits in the fifo is 1 322 | assign error_bit = |(word0[2:0] | word1[2:0] | word2[2:0] | word3[2:0] | 323 | word4[2:0] | word5[2:0] | word6[2:0] | word7[2:0] | 324 | word8[2:0] | word9[2:0] | word10[2:0] | word11[2:0] | 325 | word12[2:0] | word13[2:0] | word14[2:0] | word15[2:0] ); 326 | 327 | endmodule 328 | -------------------------------------------------------------------------------- /behavioral/wb_uart/uart_wb.v: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | //// //// 3 | //// uart_wb.v //// 4 | //// //// 5 | //// //// 6 | //// This file is part of the "UART 16550 compatible" project //// 7 | //// http://www.opencores.org/cores/uart16550/ //// 8 | //// //// 9 | //// Documentation related to this project: //// 10 | //// - http://www.opencores.org/cores/uart16550/ //// 11 | //// //// 12 | //// Projects compatibility: //// 13 | //// - WISHBONE //// 14 | //// RS232 Protocol //// 15 | //// 16550D uart (mostly supported) //// 16 | //// //// 17 | //// Overview (main Features): //// 18 | //// UART core WISHBONE interface. //// 19 | //// //// 20 | //// Known problems (limits): //// 21 | //// Inserts one wait state on all transfers. //// 22 | //// Note affected signals and the way they are affected. //// 23 | //// //// 24 | //// To Do: //// 25 | //// Nothing. //// 26 | //// //// 27 | //// Author(s): //// 28 | //// - gorban@opencores.org //// 29 | //// - Jacob Gorban //// 30 | //// - Igor Mohor (igorm@opencores.org) //// 31 | //// //// 32 | //// Created: 2001/05/12 //// 33 | //// Last Updated: 2001/05/17 //// 34 | //// (See log for the revision history) //// 35 | //// //// 36 | //// //// 37 | ////////////////////////////////////////////////////////////////////// 38 | //// //// 39 | //// Copyright (C) 2000, 2001 Authors //// 40 | //// //// 41 | //// This source file may be used and distributed without //// 42 | //// restriction provided that this copyright statement is not //// 43 | //// removed from the file and that any derivative work contains //// 44 | //// the original copyright notice and the associated disclaimer. //// 45 | //// //// 46 | //// This source file is free software; you can redistribute it //// 47 | //// and/or modify it under the terms of the GNU Lesser General //// 48 | //// Public License as published by the Free Software Foundation; //// 49 | //// either version 2.1 of the License, or (at your option) any //// 50 | //// later version. //// 51 | //// //// 52 | //// This source is distributed in the hope that it will be //// 53 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// 54 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// 55 | //// PURPOSE. See the GNU Lesser General Public License for more //// 56 | //// details. //// 57 | //// //// 58 | //// You should have received a copy of the GNU Lesser General //// 59 | //// Public License along with this source; if not, download it //// 60 | //// from http://www.opencores.org/lgpl.shtml //// 61 | //// //// 62 | ////////////////////////////////////////////////////////////////////// 63 | // 64 | // CVS Revision History 65 | // 66 | // $Log: uart_wb.v.rca $ 67 | // 68 | // Revision: 1.1.1.1 Tue Jun 7 09:39:01 2011 copew1 69 | // first stab at merging s0903a branch. 70 | // 71 | // Revision: 1.1 Fri Jun 3 12:44:14 2011 tractp1 72 | // UART in test bench to send/receive ASCII bytes with FPGA UART and 73 | // command processing task in firmware 74 | // Revision 1.16 2002/07/29 21:16:18 gorban 75 | // The uart_defines.v file is included again in sources. 76 | // 77 | // Revision 1.15 2002/07/22 23:02:23 gorban 78 | // Bug Fixes: 79 | // * Possible loss of sync and bad reception of stop bit on slow baud rates fixed. 80 | // Problem reported by Kenny.Tung. 81 | // * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers. 82 | // 83 | // Improvements: 84 | // * Made FIFO's as general inferrable memory where possible. 85 | // So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx). 86 | // This saves about 1/3 of the Slice count and reduces P&R and synthesis times. 87 | // 88 | // * Added optional baudrate output (baud_o). 89 | // This is identical to BAUDOUT* signal on 16550 chip. 90 | // It outputs 16xbit_clock_rate - the divided clock. 91 | // It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use. 92 | // 93 | // Revision 1.12 2001/12/19 08:03:34 mohor 94 | // Warnings cleared. 95 | // 96 | // Revision 1.11 2001/12/06 14:51:04 gorban 97 | // Bug in LSR[0] is fixed. 98 | // All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers. 99 | // 100 | // Revision 1.10 2001/12/03 21:44:29 gorban 101 | // Updated specification documentation. 102 | // Added full 32-bit data bus interface, now as default. 103 | // Address is 5-bit wide in 32-bit data bus mode. 104 | // Added wb_sel_i input to the core. It's used in the 32-bit mode. 105 | // Added debug interface with two 32-bit read-only registers in 32-bit mode. 106 | // Bits 5 and 6 of LSR are now only cleared on TX FIFO write. 107 | // My small test bench is modified to work with 32-bit mode. 108 | // 109 | // Revision 1.9 2001/10/20 09:58:40 gorban 110 | // Small synopsis fixes 111 | // 112 | // Revision 1.8 2001/08/24 21:01:12 mohor 113 | // Things connected to parity changed. 114 | // Clock devider changed. 115 | // 116 | // Revision 1.7 2001/08/23 16:05:05 mohor 117 | // Stop bit bug fixed. 118 | // Parity bug fixed. 119 | // WISHBONE read cycle bug fixed, 120 | // OE indicator (Overrun Error) bug fixed. 121 | // PE indicator (Parity Error) bug fixed. 122 | // Register read bug fixed. 123 | // 124 | // Revision 1.4 2001/05/31 20:08:01 gorban 125 | // FIFO changes and other corrections. 126 | // 127 | // Revision 1.3 2001/05/21 19:12:01 gorban 128 | // Corrected some Linter messages. 129 | // 130 | // Revision 1.2 2001/05/17 18:34:18 gorban 131 | // First 'stable' release. Should be sythesizable now. Also added new header. 132 | // 133 | // Revision 1.0 2001-05-17 21:27:13+02 jacob 134 | // Initial revision 135 | // 136 | // 137 | 138 | // UART core WISHBONE interface 139 | // 140 | // Author: Jacob Gorban (jacob.gorban@flextronicssemi.com) 141 | // Company: Flextronics Semiconductor 142 | // 143 | 144 | // synopsys translate_off 145 | `include "timescale.v" 146 | // synopsys translate_on 147 | `include "uart_defines.v" 148 | 149 | module uart_wb (clk, wb_rst_i, 150 | wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_adr_i, 151 | wb_adr_int, wb_dat_i, wb_dat_o, wb_dat8_i, wb_dat8_o, wb_dat32_o, wb_sel_i, 152 | we_o, re_o // Write and read enable output for the core 153 | ); 154 | 155 | input clk; 156 | 157 | // WISHBONE interface 158 | input wb_rst_i; 159 | input wb_we_i; 160 | input wb_stb_i; 161 | input wb_cyc_i; 162 | input [3:0] wb_sel_i; 163 | input [`UART_ADDR_WIDTH-1:0] wb_adr_i; //WISHBONE address line 164 | 165 | `ifdef DATA_BUS_WIDTH_8 166 | input [7:0] wb_dat_i; //input WISHBONE bus 167 | output [7:0] wb_dat_o; 168 | reg [7:0] wb_dat_o; 169 | wire [7:0] wb_dat_i; 170 | reg [7:0] wb_dat_is; 171 | `else // for 32 data bus mode 172 | input [31:0] wb_dat_i; //input WISHBONE bus 173 | output [31:0] wb_dat_o; 174 | reg [31:0] wb_dat_o; 175 | wire [31:0] wb_dat_i; 176 | reg [31:0] wb_dat_is; 177 | `endif // !`ifdef DATA_BUS_WIDTH_8 178 | 179 | output [`UART_ADDR_WIDTH-1:0] wb_adr_int; // internal signal for address bus 180 | input [7:0] wb_dat8_o; // internal 8 bit output to be put into wb_dat_o 181 | output [7:0] wb_dat8_i; 182 | input [31:0] wb_dat32_o; // 32 bit data output (for debug interface) 183 | output wb_ack_o; 184 | output we_o; 185 | output re_o; 186 | 187 | wire we_o; 188 | reg wb_ack_o; 189 | reg [7:0] wb_dat8_i; 190 | wire [7:0] wb_dat8_o; 191 | wire [`UART_ADDR_WIDTH-1:0] wb_adr_int; // internal signal for address bus 192 | reg [`UART_ADDR_WIDTH-1:0] wb_adr_is; 193 | reg wb_we_is; 194 | reg wb_cyc_is; 195 | reg wb_stb_is; 196 | reg [3:0] wb_sel_is; 197 | wire [3:0] wb_sel_i; 198 | reg wre ;// timing control signal for write or read enable 199 | 200 | // wb_ack_o FSM 201 | reg [1:0] wbstate; 202 | always @(posedge clk or posedge wb_rst_i) 203 | if (wb_rst_i) begin 204 | wb_ack_o <= #1 1'b0; 205 | wbstate <= #1 0; 206 | wre <= #1 1'b1; 207 | end else 208 | case (wbstate) 209 | 0: begin 210 | if (wb_stb_is & wb_cyc_is) begin 211 | wre <= #1 0; 212 | wbstate <= #1 1; 213 | wb_ack_o <= #1 1; 214 | end else begin 215 | wre <= #1 1; 216 | wb_ack_o <= #1 0; 217 | end 218 | end 219 | 1: begin 220 | wb_ack_o <= #1 0; 221 | wbstate <= #1 2; 222 | wre <= #1 0; 223 | end 224 | 2,3: begin 225 | wb_ack_o <= #1 0; 226 | wbstate <= #1 0; 227 | wre <= #1 0; 228 | end 229 | endcase 230 | 231 | assign we_o = wb_we_is & wb_stb_is & wb_cyc_is & wre ; //WE for registers 232 | assign re_o = ~wb_we_is & wb_stb_is & wb_cyc_is & wre ; //RE for registers 233 | 234 | // Sample input signals 235 | always @(posedge clk or posedge wb_rst_i) 236 | if (wb_rst_i) begin 237 | wb_adr_is <= #1 0; 238 | wb_we_is <= #1 0; 239 | wb_cyc_is <= #1 0; 240 | wb_stb_is <= #1 0; 241 | wb_dat_is <= #1 0; 242 | wb_sel_is <= #1 0; 243 | end else begin 244 | wb_adr_is <= #1 wb_adr_i; 245 | wb_we_is <= #1 wb_we_i; 246 | wb_cyc_is <= #1 wb_cyc_i; 247 | wb_stb_is <= #1 wb_stb_i; 248 | wb_dat_is <= #1 wb_dat_i; 249 | wb_sel_is <= #1 wb_sel_i; 250 | end 251 | 252 | `ifdef DATA_BUS_WIDTH_8 // 8-bit data bus 253 | always @(posedge clk or posedge wb_rst_i) 254 | if (wb_rst_i) 255 | wb_dat_o <= #1 0; 256 | else 257 | wb_dat_o <= #1 wb_dat8_o; 258 | 259 | always @(wb_dat_is) 260 | wb_dat8_i = wb_dat_is; 261 | 262 | assign wb_adr_int = wb_adr_is; 263 | 264 | `else // 32-bit bus 265 | // put output to the correct byte in 32 bits using select line 266 | always @(posedge clk or posedge wb_rst_i) 267 | if (wb_rst_i) 268 | wb_dat_o <= #1 0; 269 | else if (re_o) 270 | case (wb_sel_is) 271 | 4'b0000: wb_dat_o <= #1 {24'b0, wb_dat8_o}; 272 | 4'b0001: wb_dat_o <= #1 {24'b0, wb_dat8_o}; 273 | 4'b0010: wb_dat_o <= #1 {16'b0, wb_dat8_o, 8'b0}; 274 | 4'b0100: wb_dat_o <= #1 {8'b0, wb_dat8_o, 16'b0}; 275 | 4'b1000: wb_dat_o <= #1 {wb_dat8_o, 24'b0}; 276 | 4'b1111: wb_dat_o <= #1 wb_dat32_o; // debug interface output 277 | default: wb_dat_o <= #1 0; 278 | endcase // case(wb_sel_i) 279 | 280 | reg [1:0] wb_adr_int_lsb; 281 | 282 | always @(wb_sel_is or wb_dat_is) 283 | begin 284 | case (wb_sel_is) 285 | 4'b0001 : wb_dat8_i = wb_dat_is[7:0]; 286 | 4'b0010 : wb_dat8_i = wb_dat_is[15:8]; 287 | 4'b0100 : wb_dat8_i = wb_dat_is[23:16]; 288 | 4'b1000 : wb_dat8_i = wb_dat_is[31:24]; 289 | default : wb_dat8_i = wb_dat_is[7:0]; 290 | endcase // case(wb_sel_i) 291 | 292 | `ifdef LITLE_ENDIAN 293 | case (wb_sel_is) 294 | 4'b0001 : wb_adr_int_lsb = 2'h0; 295 | 4'b0010 : wb_adr_int_lsb = 2'h1; 296 | 4'b0100 : wb_adr_int_lsb = 2'h2; 297 | 4'b1000 : wb_adr_int_lsb = 2'h3; 298 | default : wb_adr_int_lsb = 2'h0; 299 | endcase // case(wb_sel_i) 300 | `else 301 | case (wb_sel_is) 302 | 4'b0001 : wb_adr_int_lsb = 2'h3; 303 | 4'b0010 : wb_adr_int_lsb = 2'h2; 304 | 4'b0100 : wb_adr_int_lsb = 2'h1; 305 | 4'b1000 : wb_adr_int_lsb = 2'h0; 306 | default : wb_adr_int_lsb = 2'h0; 307 | endcase // case(wb_sel_i) 308 | `endif 309 | end 310 | 311 | assign wb_adr_int = {wb_adr_is[`UART_ADDR_WIDTH-1:2], wb_adr_int_lsb}; 312 | 313 | `endif // !`ifdef DATA_BUS_WIDTH_8 314 | 315 | endmodule 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | -------------------------------------------------------------------------------- /behavioral/wb_uart/uart_top.v: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | //// //// 3 | //// uart_top.v //// 4 | //// //// 5 | //// //// 6 | //// This file is part of the "UART 16550 compatible" project //// 7 | //// http://www.opencores.org/cores/uart16550/ //// 8 | //// //// 9 | //// Documentation related to this project: //// 10 | //// - http://www.opencores.org/cores/uart16550/ //// 11 | //// //// 12 | //// Projects compatibility: //// 13 | //// - WISHBONE //// 14 | //// RS232 Protocol //// 15 | //// 16550D uart (mostly supported) //// 16 | //// //// 17 | //// Overview (main Features): //// 18 | //// UART core top level. //// 19 | //// //// 20 | //// Known problems (limits): //// 21 | //// Note that transmitter and receiver instances are inside //// 22 | //// the uart_regs.v file. //// 23 | //// //// 24 | //// To Do: //// 25 | //// Nothing so far. //// 26 | //// //// 27 | //// Author(s): //// 28 | //// - gorban@opencores.org //// 29 | //// - Jacob Gorban //// 30 | //// - Igor Mohor (igorm@opencores.org) //// 31 | //// //// 32 | //// Created: 2001/05/12 //// 33 | //// Last Updated: 2001/05/17 //// 34 | //// (See log for the revision history) //// 35 | //// //// 36 | //// //// 37 | ////////////////////////////////////////////////////////////////////// 38 | //// //// 39 | //// Copyright (C) 2000, 2001 Authors //// 40 | //// //// 41 | //// This source file may be used and distributed without //// 42 | //// restriction provided that this copyright statement is not //// 43 | //// removed from the file and that any derivative work contains //// 44 | //// the original copyright notice and the associated disclaimer. //// 45 | //// //// 46 | //// This source file is free software; you can redistribute it //// 47 | //// and/or modify it under the terms of the GNU Lesser General //// 48 | //// Public License as published by the Free Software Foundation; //// 49 | //// either version 2.1 of the License, or (at your option) any //// 50 | //// later version. //// 51 | //// //// 52 | //// This source is distributed in the hope that it will be //// 53 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// 54 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// 55 | //// PURPOSE. See the GNU Lesser General Public License for more //// 56 | //// details. //// 57 | //// //// 58 | //// You should have received a copy of the GNU Lesser General //// 59 | //// Public License along with this source; if not, download it //// 60 | //// from http://www.opencores.org/lgpl.shtml //// 61 | //// //// 62 | ////////////////////////////////////////////////////////////////////// 63 | // 64 | // CVS Revision History 65 | // 66 | // $Log: uart_top.v.rca $ 67 | // 68 | // Revision: 1.1.1.1 Tue Jun 7 09:39:01 2011 copew1 69 | // first stab at merging s0903a branch. 70 | // 71 | // Revision: 1.1 Fri Jun 3 12:44:14 2011 tractp1 72 | // UART in test bench to send/receive ASCII bytes with FPGA UART and 73 | // command processing task in firmware 74 | // Revision 1.18 2002/07/22 23:02:23 gorban 75 | // Bug Fixes: 76 | // * Possible loss of sync and bad reception of stop bit on slow baud rates fixed. 77 | // Problem reported by Kenny.Tung. 78 | // * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers. 79 | // 80 | // Improvements: 81 | // * Made FIFO's as general inferrable memory where possible. 82 | // So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx). 83 | // This saves about 1/3 of the Slice count and reduces P&R and synthesis times. 84 | // 85 | // * Added optional baudrate output (baud_o). 86 | // This is identical to BAUDOUT* signal on 16550 chip. 87 | // It outputs 16xbit_clock_rate - the divided clock. 88 | // It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use. 89 | // 90 | // Revision 1.17 2001/12/19 08:40:03 mohor 91 | // Warnings fixed (unused signals removed). 92 | // 93 | // Revision 1.16 2001/12/06 14:51:04 gorban 94 | // Bug in LSR[0] is fixed. 95 | // All WISHBONE signals are now sampled, so another wait-state is introduced on all transfers. 96 | // 97 | // Revision 1.15 2001/12/03 21:44:29 gorban 98 | // Updated specification documentation. 99 | // Added full 32-bit data bus interface, now as default. 100 | // Address is 5-bit wide in 32-bit data bus mode. 101 | // Added wb_sel_i input to the core. It's used in the 32-bit mode. 102 | // Added debug interface with two 32-bit read-only registers in 32-bit mode. 103 | // Bits 5 and 6 of LSR are now only cleared on TX FIFO write. 104 | // My small test bench is modified to work with 32-bit mode. 105 | // 106 | // Revision 1.14 2001/11/07 17:51:52 gorban 107 | // Heavily rewritten interrupt and LSR subsystems. 108 | // Many bugs hopefully squashed. 109 | // 110 | // Revision 1.13 2001/10/20 09:58:40 gorban 111 | // Small synopsis fixes 112 | // 113 | // Revision 1.12 2001/08/25 15:46:19 gorban 114 | // Modified port names again 115 | // 116 | // Revision 1.11 2001/08/24 21:01:12 mohor 117 | // Things connected to parity changed. 118 | // Clock devider changed. 119 | // 120 | // Revision 1.10 2001/08/23 16:05:05 mohor 121 | // Stop bit bug fixed. 122 | // Parity bug fixed. 123 | // WISHBONE read cycle bug fixed, 124 | // OE indicator (Overrun Error) bug fixed. 125 | // PE indicator (Parity Error) bug fixed. 126 | // Register read bug fixed. 127 | // 128 | // Revision 1.4 2001/05/31 20:08:01 gorban 129 | // FIFO changes and other corrections. 130 | // 131 | // Revision 1.3 2001/05/21 19:12:02 gorban 132 | // Corrected some Linter messages. 133 | // 134 | // Revision 1.2 2001/05/17 18:34:18 gorban 135 | // First 'stable' release. Should be sythesizable now. Also added new header. 136 | // 137 | // Revision 1.0 2001-05-17 21:27:12+02 jacob 138 | // Initial revision 139 | // 140 | // 141 | // synopsys translate_off 142 | `include "timescale.v" 143 | // synopsys translate_on 144 | 145 | `include "uart_defines.v" 146 | 147 | module uart_top ( 148 | wb_clk_i, 149 | 150 | // Wishbone signals 151 | wb_rst_i, wb_adr_i, wb_dat_i, wb_dat_o, wb_we_i, wb_stb_i, wb_cyc_i, wb_ack_o, wb_sel_i, 152 | int_o, // interrupt request 153 | 154 | // UART signals 155 | // serial input/output 156 | stx_pad_o, srx_pad_i, 157 | 158 | // modem signals 159 | rts_pad_o, cts_pad_i, dtr_pad_o, dsr_pad_i, ri_pad_i, dcd_pad_i 160 | `ifdef UART_HAS_BAUDRATE_OUTPUT 161 | , baud_o 162 | `endif 163 | ); 164 | 165 | parameter uart_data_width = `UART_DATA_WIDTH; 166 | parameter uart_addr_width = `UART_ADDR_WIDTH; 167 | 168 | input wb_clk_i; 169 | 170 | // WISHBONE interface 171 | input wb_rst_i; 172 | input [uart_addr_width-1:0] wb_adr_i; 173 | input [uart_data_width-1:0] wb_dat_i; 174 | output [uart_data_width-1:0] wb_dat_o; 175 | input wb_we_i; 176 | input wb_stb_i; 177 | input wb_cyc_i; 178 | input [3:0] wb_sel_i; 179 | output wb_ack_o; 180 | output int_o; 181 | 182 | // UART signals 183 | input srx_pad_i; 184 | output stx_pad_o; 185 | output rts_pad_o; 186 | input cts_pad_i; 187 | output dtr_pad_o; 188 | input dsr_pad_i; 189 | input ri_pad_i; 190 | input dcd_pad_i; 191 | 192 | // optional baudrate output 193 | `ifdef UART_HAS_BAUDRATE_OUTPUT 194 | output baud_o; 195 | `endif 196 | 197 | 198 | wire stx_pad_o; 199 | wire rts_pad_o; 200 | wire dtr_pad_o; 201 | 202 | wire [uart_addr_width-1:0] wb_adr_i; 203 | wire [uart_data_width-1:0] wb_dat_i; 204 | wire [uart_data_width-1:0] wb_dat_o; 205 | 206 | wire [7:0] wb_dat8_i; // 8-bit internal data input 207 | wire [7:0] wb_dat8_o; // 8-bit internal data output 208 | wire [31:0] wb_dat32_o; // debug interface 32-bit output 209 | wire [3:0] wb_sel_i; // WISHBONE select signal 210 | wire [uart_addr_width-1:0] wb_adr_int; 211 | wire we_o; // Write enable for registers 212 | wire re_o; // Read enable for registers 213 | // 214 | // MODULE INSTANCES 215 | // 216 | 217 | `ifdef DATA_BUS_WIDTH_8 218 | `else 219 | // debug interface wires 220 | wire [3:0] ier; 221 | wire [3:0] iir; 222 | wire [1:0] fcr; 223 | wire [4:0] mcr; 224 | wire [7:0] lcr; 225 | wire [7:0] msr; 226 | wire [7:0] lsr; 227 | wire [`UART_FIFO_COUNTER_W-1:0] rf_count; 228 | wire [`UART_FIFO_COUNTER_W-1:0] tf_count; 229 | wire [2:0] tstate; 230 | wire [3:0] rstate; 231 | `endif 232 | 233 | `ifdef DATA_BUS_WIDTH_8 234 | //// WISHBONE interface module 235 | uart_wb wb_interface( 236 | .clk( wb_clk_i ), 237 | .wb_rst_i( wb_rst_i ), 238 | .wb_dat_i(wb_dat_i), 239 | .wb_dat_o(wb_dat_o), 240 | .wb_dat8_i(wb_dat8_i), 241 | .wb_dat8_o(wb_dat8_o), 242 | .wb_dat32_o(32'b0), 243 | .wb_sel_i(4'b0), 244 | .wb_we_i( wb_we_i ), 245 | .wb_stb_i( wb_stb_i ), 246 | .wb_cyc_i( wb_cyc_i ), 247 | .wb_ack_o( wb_ack_o ), 248 | .wb_adr_i(wb_adr_i), 249 | .wb_adr_int(wb_adr_int), 250 | .we_o( we_o ), 251 | .re_o(re_o) 252 | ); 253 | `else 254 | uart_wb wb_interface( 255 | .clk( wb_clk_i ), 256 | .wb_rst_i( wb_rst_i ), 257 | .wb_dat_i(wb_dat_i), 258 | .wb_dat_o(wb_dat_o), 259 | .wb_dat8_i(wb_dat8_i), 260 | .wb_dat8_o(wb_dat8_o), 261 | .wb_sel_i(wb_sel_i), 262 | .wb_dat32_o(wb_dat32_o), 263 | .wb_we_i( wb_we_i ), 264 | .wb_stb_i( wb_stb_i ), 265 | .wb_cyc_i( wb_cyc_i ), 266 | .wb_ack_o( wb_ack_o ), 267 | .wb_adr_i(wb_adr_i), 268 | .wb_adr_int(wb_adr_int), 269 | .we_o( we_o ), 270 | .re_o(re_o) 271 | ); 272 | `endif 273 | 274 | // Registers 275 | uart_regs regs( 276 | .clk( wb_clk_i ), 277 | .wb_rst_i( wb_rst_i ), 278 | .wb_addr_i( wb_adr_int ), 279 | .wb_dat_i( wb_dat8_i ), 280 | .wb_dat_o( wb_dat8_o ), 281 | .wb_we_i( we_o ), 282 | .wb_re_i(re_o), 283 | .modem_inputs( {cts_pad_i, dsr_pad_i, 284 | ri_pad_i, dcd_pad_i} ), 285 | .stx_pad_o( stx_pad_o ), 286 | .srx_pad_i( srx_pad_i ), 287 | `ifdef DATA_BUS_WIDTH_8 288 | `else 289 | // debug interface signals enabled 290 | .ier(ier), 291 | .iir(iir), 292 | .fcr(fcr), 293 | .mcr(mcr), 294 | .lcr(lcr), 295 | .msr(msr), 296 | .lsr(lsr), 297 | .rf_count(rf_count), 298 | .tf_count(tf_count), 299 | .tstate(tstate), 300 | .rstate(rstate), 301 | `endif 302 | .rts_pad_o( rts_pad_o ), 303 | .dtr_pad_o( dtr_pad_o ), 304 | .int_o( int_o ) 305 | `ifdef UART_HAS_BAUDRATE_OUTPUT 306 | , .baud_o(baud_o) 307 | `endif 308 | 309 | ); 310 | 311 | `ifdef DATA_BUS_WIDTH_8 312 | `else 313 | uart_debug_if dbg(/*AUTOINST*/ 314 | // Outputs 315 | .wb_dat32_o (wb_dat32_o[31:0]), 316 | // Inputs 317 | .wb_adr_i (wb_adr_int[`UART_ADDR_WIDTH-1:0]), 318 | .ier (ier[3:0]), 319 | .iir (iir[3:0]), 320 | .fcr (fcr[1:0]), 321 | .mcr (mcr[4:0]), 322 | .lcr (lcr[7:0]), 323 | .msr (msr[7:0]), 324 | .lsr (lsr[7:0]), 325 | .rf_count (rf_count[`UART_FIFO_COUNTER_W-1:0]), 326 | .tf_count (tf_count[`UART_FIFO_COUNTER_W-1:0]), 327 | .tstate (tstate[2:0]), 328 | .rstate (rstate[3:0])); 329 | `endif 330 | 331 | initial 332 | begin 333 | `ifdef DATA_BUS_WIDTH_8 334 | $display("(%m) UART INFO: Data bus width is 8. No Debug interface.\n"); 335 | `else 336 | $display("(%m) UART INFO: Data bus width is 32. Debug Interface present.\n"); 337 | `endif 338 | `ifdef UART_HAS_BAUDRATE_OUTPUT 339 | $display("(%m) UART INFO: Has baudrate output\n"); 340 | `else 341 | $display("(%m) UART INFO: Doesn't have baudrate output\n"); 342 | `endif 343 | end 344 | 345 | endmodule 346 | 347 | 348 | -------------------------------------------------------------------------------- /behavioral/wb_uart/uart_transmitter.v: -------------------------------------------------------------------------------- 1 | ////////////////////////////////////////////////////////////////////// 2 | //// //// 3 | //// uart_transmitter.v //// 4 | //// //// 5 | //// //// 6 | //// This file is part of the "UART 16550 compatible" project //// 7 | //// http://www.opencores.org/cores/uart16550/ //// 8 | //// //// 9 | //// Documentation related to this project: //// 10 | //// - http://www.opencores.org/cores/uart16550/ //// 11 | //// //// 12 | //// Projects compatibility: //// 13 | //// - WISHBONE //// 14 | //// RS232 Protocol //// 15 | //// 16550D uart (mostly supported) //// 16 | //// //// 17 | //// Overview (main Features): //// 18 | //// UART core transmitter logic //// 19 | //// //// 20 | //// Known problems (limits): //// 21 | //// None known //// 22 | //// //// 23 | //// To Do: //// 24 | //// Thourough testing. //// 25 | //// //// 26 | //// Author(s): //// 27 | //// - gorban@opencores.org //// 28 | //// - Jacob Gorban //// 29 | //// - Igor Mohor (igorm@opencores.org) //// 30 | //// //// 31 | //// Created: 2001/05/12 //// 32 | //// Last Updated: 2001/05/17 //// 33 | //// (See log for the revision history) //// 34 | //// //// 35 | //// //// 36 | ////////////////////////////////////////////////////////////////////// 37 | //// //// 38 | //// Copyright (C) 2000, 2001 Authors //// 39 | //// //// 40 | //// This source file may be used and distributed without //// 41 | //// restriction provided that this copyright statement is not //// 42 | //// removed from the file and that any derivative work contains //// 43 | //// the original copyright notice and the associated disclaimer. //// 44 | //// //// 45 | //// This source file is free software; you can redistribute it //// 46 | //// and/or modify it under the terms of the GNU Lesser General //// 47 | //// Public License as published by the Free Software Foundation; //// 48 | //// either version 2.1 of the License, or (at your option) any //// 49 | //// later version. //// 50 | //// //// 51 | //// This source is distributed in the hope that it will be //// 52 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// 53 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// 54 | //// PURPOSE. See the GNU Lesser General Public License for more //// 55 | //// details. //// 56 | //// //// 57 | //// You should have received a copy of the GNU Lesser General //// 58 | //// Public License along with this source; if not, download it //// 59 | //// from http://www.opencores.org/lgpl.shtml //// 60 | //// //// 61 | ////////////////////////////////////////////////////////////////////// 62 | // 63 | // CVS Revision History 64 | // 65 | // $Log: uart_transmitter.v.rca $ 66 | // 67 | // Revision: 1.1.1.1 Tue Jun 7 09:39:01 2011 copew1 68 | // first stab at merging s0903a branch. 69 | // 70 | // Revision: 1.1 Fri Jun 3 12:44:13 2011 tractp1 71 | // UART in test bench to send/receive ASCII bytes with FPGA UART and 72 | // command processing task in firmware 73 | // Revision 1.18 2002/07/22 23:02:23 gorban 74 | // Bug Fixes: 75 | // * Possible loss of sync and bad reception of stop bit on slow baud rates fixed. 76 | // Problem reported by Kenny.Tung. 77 | // * Bad (or lack of ) loopback handling fixed. Reported by Cherry Withers. 78 | // 79 | // Improvements: 80 | // * Made FIFO's as general inferrable memory where possible. 81 | // So on FPGA they should be inferred as RAM (Distributed RAM on Xilinx). 82 | // This saves about 1/3 of the Slice count and reduces P&R and synthesis times. 83 | // 84 | // * Added optional baudrate output (baud_o). 85 | // This is identical to BAUDOUT* signal on 16550 chip. 86 | // It outputs 16xbit_clock_rate - the divided clock. 87 | // It's disabled by default. Define UART_HAS_BAUDRATE_OUTPUT to use. 88 | // 89 | // Revision 1.16 2002/01/08 11:29:40 mohor 90 | // tf_pop was too wide. Now it is only 1 clk cycle width. 91 | // 92 | // Revision 1.15 2001/12/17 14:46:48 mohor 93 | // overrun signal was moved to separate block because many sequential lsr 94 | // reads were preventing data from being written to rx fifo. 95 | // underrun signal was not used and was removed from the project. 96 | // 97 | // Revision 1.14 2001/12/03 21:44:29 gorban 98 | // Updated specification documentation. 99 | // Added full 32-bit data bus interface, now as default. 100 | // Address is 5-bit wide in 32-bit data bus mode. 101 | // Added wb_sel_i input to the core. It's used in the 32-bit mode. 102 | // Added debug interface with two 32-bit read-only registers in 32-bit mode. 103 | // Bits 5 and 6 of LSR are now only cleared on TX FIFO write. 104 | // My small test bench is modified to work with 32-bit mode. 105 | // 106 | // Revision 1.13 2001/11/08 14:54:23 mohor 107 | // Comments in Slovene language deleted, few small fixes for better work of 108 | // old tools. IRQs need to be fix. 109 | // 110 | // Revision 1.12 2001/11/07 17:51:52 gorban 111 | // Heavily rewritten interrupt and LSR subsystems. 112 | // Many bugs hopefully squashed. 113 | // 114 | // Revision 1.11 2001/10/29 17:00:46 gorban 115 | // fixed parity sending and tx_fifo resets over- and underrun 116 | // 117 | // Revision 1.10 2001/10/20 09:58:40 gorban 118 | // Small synopsis fixes 119 | // 120 | // Revision 1.9 2001/08/24 21:01:12 mohor 121 | // Things connected to parity changed. 122 | // Clock devider changed. 123 | // 124 | // Revision 1.8 2001/08/23 16:05:05 mohor 125 | // Stop bit bug fixed. 126 | // Parity bug fixed. 127 | // WISHBONE read cycle bug fixed, 128 | // OE indicator (Overrun Error) bug fixed. 129 | // PE indicator (Parity Error) bug fixed. 130 | // Register read bug fixed. 131 | // 132 | // Revision 1.6 2001/06/23 11:21:48 gorban 133 | // DL made 16-bit long. Fixed transmission/reception bugs. 134 | // 135 | // Revision 1.5 2001/06/02 14:28:14 gorban 136 | // Fixed receiver and transmitter. Major bug fixed. 137 | // 138 | // Revision 1.4 2001/05/31 20:08:01 gorban 139 | // FIFO changes and other corrections. 140 | // 141 | // Revision 1.3 2001/05/27 17:37:49 gorban 142 | // Fixed many bugs. Updated spec. Changed FIFO files structure. See CHANGES.txt file. 143 | // 144 | // Revision 1.2 2001/05/21 19:12:02 gorban 145 | // Corrected some Linter messages. 146 | // 147 | // Revision 1.1 2001/05/17 18:34:18 gorban 148 | // First 'stable' release. Should be sythesizable now. Also added new header. 149 | // 150 | // Revision 1.0 2001-05-17 21:27:12+02 jacob 151 | // Initial revision 152 | // 153 | // 154 | 155 | // synopsys translate_off 156 | `include "timescale.v" 157 | // synopsys translate_on 158 | 159 | `include "uart_defines.v" 160 | 161 | module uart_transmitter (clk, wb_rst_i, lcr, tf_push, wb_dat_i, enable, stx_pad_o, tstate, tf_count, tx_reset, lsr_mask); 162 | 163 | input clk; 164 | input wb_rst_i; 165 | input [7:0] lcr; 166 | input tf_push; 167 | input [7:0] wb_dat_i; 168 | input enable; 169 | input tx_reset; 170 | input lsr_mask; //reset of fifo 171 | output stx_pad_o; 172 | output [2:0] tstate; 173 | output [`UART_FIFO_COUNTER_W-1:0] tf_count; 174 | 175 | reg [2:0] tstate; 176 | reg [4:0] counter; 177 | reg [2:0] bit_counter; // counts the bits to be sent 178 | reg [6:0] shift_out; // output shift register 179 | reg stx_o_tmp; 180 | reg parity_xor; // parity of the word 181 | reg tf_pop; 182 | reg bit_out; 183 | 184 | // TX FIFO instance 185 | // 186 | // Transmitter FIFO signals 187 | wire [`UART_FIFO_WIDTH-1:0] tf_data_in; 188 | wire [`UART_FIFO_WIDTH-1:0] tf_data_out; 189 | wire tf_push; 190 | wire tf_overrun; 191 | wire [`UART_FIFO_COUNTER_W-1:0] tf_count; 192 | 193 | assign tf_data_in = wb_dat_i; 194 | 195 | uart_tfifo fifo_tx( // error bit signal is not used in transmitter FIFO 196 | .clk( clk ), 197 | .wb_rst_i( wb_rst_i ), 198 | .data_in( tf_data_in ), 199 | .data_out( tf_data_out ), 200 | .push( tf_push ), 201 | .pop( tf_pop ), 202 | .overrun( tf_overrun ), 203 | .count( tf_count ), 204 | .fifo_reset( tx_reset ), 205 | .reset_status(lsr_mask) 206 | ); 207 | 208 | // TRANSMITTER FINAL STATE MACHINE 209 | 210 | parameter s_idle = 3'd0; 211 | parameter s_send_start = 3'd1; 212 | parameter s_send_byte = 3'd2; 213 | parameter s_send_parity = 3'd3; 214 | parameter s_send_stop = 3'd4; 215 | parameter s_pop_byte = 3'd5; 216 | 217 | always @(posedge clk or posedge wb_rst_i) 218 | begin 219 | if (wb_rst_i) 220 | begin 221 | tstate <= #1 s_idle; 222 | stx_o_tmp <= #1 1'b1; 223 | counter <= #1 5'b0; 224 | shift_out <= #1 7'b0; 225 | bit_out <= #1 1'b0; 226 | parity_xor <= #1 1'b0; 227 | tf_pop <= #1 1'b0; 228 | bit_counter <= #1 3'b0; 229 | end 230 | else 231 | if (enable) 232 | begin 233 | case (tstate) 234 | s_idle : if (~|tf_count) // if tf_count==0 235 | begin 236 | tstate <= #1 s_idle; 237 | stx_o_tmp <= #1 1'b1; 238 | end 239 | else 240 | begin 241 | tf_pop <= #1 1'b0; 242 | stx_o_tmp <= #1 1'b1; 243 | tstate <= #1 s_pop_byte; 244 | end 245 | s_pop_byte : begin 246 | tf_pop <= #1 1'b1; 247 | case (lcr[/*`UART_LC_BITS*/1:0]) // number of bits in a word 248 | 2'b00 : begin 249 | bit_counter <= #1 3'b100; 250 | parity_xor <= #1 ^tf_data_out[4:0]; 251 | end 252 | 2'b01 : begin 253 | bit_counter <= #1 3'b101; 254 | parity_xor <= #1 ^tf_data_out[5:0]; 255 | end 256 | 2'b10 : begin 257 | bit_counter <= #1 3'b110; 258 | parity_xor <= #1 ^tf_data_out[6:0]; 259 | end 260 | 2'b11 : begin 261 | bit_counter <= #1 3'b111; 262 | parity_xor <= #1 ^tf_data_out[7:0]; 263 | end 264 | endcase 265 | {shift_out[6:0], bit_out} <= #1 tf_data_out; 266 | tstate <= #1 s_send_start; 267 | end 268 | s_send_start : begin 269 | tf_pop <= #1 1'b0; 270 | if (~|counter) 271 | counter <= #1 5'b01111; 272 | else 273 | if (counter == 5'b00001) 274 | begin 275 | counter <= #1 0; 276 | tstate <= #1 s_send_byte; 277 | end 278 | else 279 | counter <= #1 counter - 1'b1; 280 | stx_o_tmp <= #1 1'b0; 281 | end 282 | s_send_byte : begin 283 | if (~|counter) 284 | counter <= #1 5'b01111; 285 | else 286 | if (counter == 5'b00001) 287 | begin 288 | if (bit_counter > 3'b0) 289 | begin 290 | bit_counter <= #1 bit_counter - 1'b1; 291 | {shift_out[5:0],bit_out } <= #1 {shift_out[6:1], shift_out[0]}; 292 | tstate <= #1 s_send_byte; 293 | end 294 | else // end of byte 295 | if (~lcr[`UART_LC_PE]) 296 | begin 297 | tstate <= #1 s_send_stop; 298 | end 299 | else 300 | begin 301 | case ({lcr[`UART_LC_EP],lcr[`UART_LC_SP]}) 302 | 2'b00: bit_out <= #1 ~parity_xor; 303 | 2'b01: bit_out <= #1 1'b1; 304 | 2'b10: bit_out <= #1 parity_xor; 305 | 2'b11: bit_out <= #1 1'b0; 306 | endcase 307 | tstate <= #1 s_send_parity; 308 | end 309 | counter <= #1 0; 310 | end 311 | else 312 | counter <= #1 counter - 1'b1; 313 | stx_o_tmp <= #1 bit_out; // set output pin 314 | end 315 | s_send_parity : begin 316 | if (~|counter) 317 | counter <= #1 5'b01111; 318 | else 319 | if (counter == 5'b00001) 320 | begin 321 | counter <= #1 4'b0; 322 | tstate <= #1 s_send_stop; 323 | end 324 | else 325 | counter <= #1 counter - 1'b1; 326 | stx_o_tmp <= #1 bit_out; 327 | end 328 | s_send_stop : begin 329 | if (~|counter) 330 | begin 331 | casex ({lcr[`UART_LC_SB],lcr[`UART_LC_BITS]}) 332 | 3'b0xx: counter <= #1 5'b01101; // 1 stop bit ok igor 333 | 3'b100: counter <= #1 5'b10101; // 1.5 stop bit 334 | default: counter <= #1 5'b11101; // 2 stop bits 335 | endcase 336 | end 337 | else 338 | if (counter == 5'b00001) 339 | begin 340 | counter <= #1 0; 341 | tstate <= #1 s_idle; 342 | end 343 | else 344 | counter <= #1 counter - 1'b1; 345 | stx_o_tmp <= #1 1'b1; 346 | end 347 | 348 | default : // should never get here 349 | tstate <= #1 s_idle; 350 | endcase 351 | end // end if enable 352 | else 353 | tf_pop <= #1 1'b0; // tf_pop must be 1 cycle width 354 | end // transmitter logic 355 | 356 | assign stx_pad_o = lcr[`UART_LC_BC] ? 1'b0 : stx_o_tmp; // Break condition 357 | 358 | endmodule 359 | -------------------------------------------------------------------------------- /behavioral/wb_master/wb_mast_model.v: -------------------------------------------------------------------------------- 1 | ///////////////////////////////////////////////////////////////////// 2 | //// //// 3 | //// WISHBONE Master Model //// 4 | //// //// 5 | //// //// 6 | //// Author: Rudolf Usselmann //// 7 | //// rudi@asics.ws //// 8 | //// //// 9 | //// //// 10 | ///////////////////////////////////////////////////////////////////// 11 | //// //// 12 | //// Copyright (C) 2000-2002 Rudolf Usselmann //// 13 | //// www.asics.ws //// 14 | //// rudi@asics.ws //// 15 | //// //// 16 | //// This source file may be used and distributed without //// 17 | //// restriction provided that this copyright statement is not //// 18 | //// removed from the file and that any derivative work contains //// 19 | //// the original copyright notice and the associated disclaimer.//// 20 | //// //// 21 | //// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY //// 22 | //// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED //// 23 | //// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS //// 24 | //// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR //// 25 | //// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, //// 26 | //// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES //// 27 | //// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE //// 28 | //// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR //// 29 | //// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF //// 30 | //// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT //// 31 | //// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT //// 32 | //// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE //// 33 | //// POSSIBILITY OF SUCH DAMAGE. //// 34 | //// //// 35 | ///////////////////////////////////////////////////////////////////// 36 | 37 | // CVS Log 38 | // 39 | // $Id: wb_mast_model.v.rca 1.1.1.1 Tue Jun 7 09:38:58 2011 copew1 Experimental haskis1 haskis1 $ 40 | // 41 | // $Date: Tue Jun 7 09:38:58 2011 $ 42 | // $Revision: 1.1.1.1 $ 43 | // $Author: copew1 $ 44 | // $Locker: haskis1 haskis1 $ 45 | // $State: Experimental $ 46 | // 47 | // Change History: 48 | // $Log: wb_mast_model.v.rca $ 49 | // 50 | // Revision: 1.1.1.1 Tue Jun 7 09:38:58 2011 copew1 51 | // first stab at merging s0903a branch. 52 | // 53 | // Revision: 1.1 Fri Jun 3 12:43:38 2011 tractp1 54 | // wishbone master to control UART in test bench 55 | // Revision 1.2 2002/10/03 05:40:03 rudi 56 | // Fixed a minor bug in parameter passing, updated headers and specification. 57 | // 58 | // Revision 1.1.1.1 2001/10/19 11:04:23 rudi 59 | // WISHBONE CONMAX IP Core 60 | // 61 | // 62 | // 63 | // 64 | // 65 | 66 | `include "wb_model_defines.v" 67 | 68 | module wb_mast(clk, rst, adr, din, dout, cyc, stb, sel, we, ack, err, rty); 69 | 70 | input clk, rst; 71 | output [31:0] adr; 72 | input [31:0] din; 73 | output [31:0] dout; 74 | output cyc, stb; 75 | output [3:0] sel; 76 | output we; 77 | input ack, err, rty; 78 | 79 | //////////////////////////////////////////////////////////////////// 80 | // 81 | // Local Wires 82 | // 83 | 84 | parameter mem_size = 4096; 85 | 86 | reg [31:0] adr; 87 | reg [31:0] dout; 88 | reg cyc, stb; 89 | reg [3:0] sel; 90 | reg we; 91 | 92 | reg [31:0] mem[mem_size:0]; 93 | integer cnt; 94 | 95 | //////////////////////////////////////////////////////////////////// 96 | // 97 | // Memory Logic 98 | // 99 | 100 | initial 101 | begin 102 | //adr = 32'hxxxx_xxxx; 103 | //adr = 0; 104 | adr = 32'hffff_ffff; 105 | dout = 32'hxxxx_xxxx; 106 | cyc = 0; 107 | stb = 0; 108 | sel = 4'hx; 109 | we = 1'hx; 110 | cnt = 0; 111 | #1; 112 | $display("\nINFO: WISHBONE MASTER MODEL INSTANTIATED (%m)\n"); 113 | end 114 | 115 | 116 | 117 | task mem_fill; 118 | 119 | integer n; 120 | begin 121 | cnt = 0; 122 | cnt = 0; 123 | for(n=0;n wait for break or srx_pad_i 416 | begin 417 | rf_data_in <= #1 {rshift, 1'b0, rparity_error, rframing_error}; 418 | rf_push <= #1 1'b1; 419 | rcounter16 <= #1 4'b1110; 420 | rstate <= #1 sr_rec_start; 421 | end 422 | 423 | end 424 | default : rstate <= #1 sr_idle; 425 | endcase 426 | end // if (enable) 427 | end // always of receiver 428 | 429 | always @ (posedge clk or posedge wb_rst_i) 430 | begin 431 | if(wb_rst_i) 432 | rf_push_q <= 0; 433 | else 434 | rf_push_q <= #1 rf_push; 435 | end 436 | 437 | assign rf_push_pulse = rf_push & ~rf_push_q; 438 | 439 | 440 | // 441 | // Break condition detection. 442 | // Works in conjuction with the receiver state machine 443 | 444 | reg [9:0] toc_value; // value to be set to timeout counter 445 | 446 | always @(lcr) 447 | case (lcr[3:0]) 448 | 4'b0000 : toc_value = 447; // 7 bits 449 | 4'b0100 : toc_value = 479; // 7.5 bits 450 | 4'b0001, 4'b1000 : toc_value = 511; // 8 bits 451 | 4'b1100 : toc_value = 543; // 8.5 bits 452 | 4'b0010, 4'b0101, 4'b1001 : toc_value = 575; // 9 bits 453 | 4'b0011, 4'b0110, 4'b1010, 4'b1101 : toc_value = 639; // 10 bits 454 | 4'b0111, 4'b1011, 4'b1110 : toc_value = 703; // 11 bits 455 | 4'b1111 : toc_value = 767; // 12 bits 456 | endcase // case(lcr[3:0]) 457 | 458 | wire [7:0] brc_value; // value to be set to break counter 459 | assign brc_value = toc_value[9:2]; // the same as timeout but 1 insead of 4 character times 460 | 461 | always @(posedge clk or posedge wb_rst_i) 462 | begin 463 | if (wb_rst_i) 464 | counter_b <= #1 8'd159; 465 | else 466 | if (srx_pad_i) 467 | counter_b <= #1 brc_value; // character time length - 1 468 | else 469 | if(enable & counter_b != 8'b0) // only work on enable times break not reached. 470 | counter_b <= #1 counter_b - 1; // decrement break counter 471 | end // always of break condition detection 472 | 473 | /// 474 | /// Timeout condition detection 475 | reg [9:0] counter_t; // counts the timeout condition clocks 476 | 477 | always @(posedge clk or posedge wb_rst_i) 478 | begin 479 | if (wb_rst_i) 480 | counter_t <= #1 10'd639; // 10 bits for the default 8N1 481 | else 482 | if(rf_push_pulse || rf_pop || rf_count == 0) // counter is reset when RX FIFO is empty, accessed or above trigger level 483 | counter_t <= #1 toc_value; 484 | else 485 | if (enable && counter_t != 10'b0) // we don't want to underflow 486 | counter_t <= #1 counter_t - 1; 487 | end 488 | 489 | endmodule // uart_receiver 490 | 491 | --------------------------------------------------------------------------------