URL
https://opencores.org/ocsvn/rs232_syscon/rs232_syscon/trunk
Subversion Repositories rs232_syscon
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 8 to Rev 7
- ↔ Reverse comparison
Rev 8 → Rev 7
/rs232_syscon/trunk/verilog/rs232_syscon.v
File deleted
/rs232_syscon/trunk/verilog/b13c_environment.zip
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
rs232_syscon/trunk/verilog/b13c_environment.zip
Property changes :
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: rs232_syscon/trunk/verilog_doc/rs232_syscon.doc
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: rs232_syscon/trunk/verilog_doc/rs232_syscon.doc
===================================================================
--- rs232_syscon/trunk/verilog_doc/rs232_syscon.doc (revision 8)
+++ rs232_syscon/trunk/verilog_doc/rs232_syscon.doc (nonexistent)
rs232_syscon/trunk/verilog_doc/rs232_syscon.doc
Property changes :
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: rs232_syscon/trunk/VHDL/syscon_vhdl_LED_strobe_2_with_ADC_altera_project.qar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: rs232_syscon/trunk/VHDL/syscon_vhdl_LED_strobe_2_with_ADC_altera_project.qar
===================================================================
--- rs232_syscon/trunk/VHDL/syscon_vhdl_LED_strobe_2_with_ADC_altera_project.qar (revision 8)
+++ rs232_syscon/trunk/VHDL/syscon_vhdl_LED_strobe_2_with_ADC_altera_project.qar (nonexistent)
rs232_syscon/trunk/VHDL/syscon_vhdl_LED_strobe_2_with_ADC_altera_project.qar
Property changes :
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: rs232_syscon/trunk/VHDL/uart_sqclk_pack.vhd
===================================================================
--- rs232_syscon/trunk/VHDL/uart_sqclk_pack.vhd (revision 8)
+++ rs232_syscon/trunk/VHDL/uart_sqclk_pack.vhd (nonexistent)
@@ -1,716 +0,0 @@
---------------------------------------------------------------------------
--- Package of UART components
---
--- This UART uses a squarewave input for the BAUDRATE clock. In other
--- words, the BAUD rate is exactly the same as the frequency of the
--- incoming clock. This is in contrast to other UARTs which need a
--- Baud rate clock which is some multiple of the actual Baud rate
--- desired. Because of the 1x nature of the Baud clock, the receiver
--- needs at least one Baud Clock interval in which to measure the
--- Baud clock versus the system clock, before it can start working.
--- Also, the system clock must be somewhat higher than the Baud clock
--- in order for the receiver to work.
---
--- This package contains the UART, plus individual async_tx and async_rx
--- modules, which are the transmit and receive sections of the UART.
---
---
-
-library IEEE;
-use IEEE.STD_LOGIC_1164.ALL;
-use IEEE.NUMERIC_STD.ALL;
-
-package uart_sqclk_pack is
-
- component uart_sqclk
- port (
-
- sys_rst_n : in std_logic;
- sys_clk : in std_logic;
- sys_clk_en : in std_logic;
-
- -- rate and parity
- parity_i : in unsigned(1 downto 0); -- 0=none, 1=even, 2 or 3=odd
- rate_clk_i : in std_logic;
-
- -- serial I/O
- tx_stream : out std_logic;
- rx_stream : in std_logic;
-
- --control and status
- tx_wr_i : in std_logic; -- Starts Transmit
- tx_dat_i : in unsigned(7 downto 0);
- tx_done_o : out std_logic;
- rx_restart_i : in std_logic; -- High clears error flags, clears rx_done_o
- rx_dat_o : out unsigned(7 downto 0);
- rx_wr_o : out std_logic; -- High pulse means store rx_dat_o.
- rx_done_o : out std_logic; -- Remains high after receive, until clk edge with rx_restart_i=1
- frame_err_o : out std_logic; -- High = error. Reset when rx_restart_i asserted.
- parity_err_o : out std_logic -- High = error. Reset when rx_restart_i asserted.
- );
- end component;
-
- component async_tx_sqclk
- port (
-
- sys_rst_n : in std_logic;
- sys_clk : in std_logic;
- sys_clk_en : in std_logic;
-
- -- rate and parity
- tx_parity_i : in unsigned(1 downto 0); -- 0=none, 1=even, 2 or 3=odd
- tx_clk_i : in std_logic;
-
- -- serial output
- tx_stream : out std_logic;
-
- -- control and status
- tx_wr_i : in std_logic; -- Starts Transmit
- tx_dat_i : in unsigned(7 downto 0);
- tx_done_o : out std_logic
- );
- end component;
-
-
- component async_rx_sqclk
- port (
-
- sys_rst_n : in std_logic;
- sys_clk : in std_logic;
- sys_clk_en : in std_logic;
-
- -- rate and parity
- rx_parity_i : in unsigned(1 downto 0); -- 0=none, 1=even, 2 or 3=odd
- rx_clk_i : in std_logic;
-
- -- serial input
- rx_stream : in std_logic;
-
- -- control and status
- rx_restart_i : in std_logic; -- High clears error flags, clears rx_done_o
- rx_dat_o : out unsigned(7 downto 0);
- rx_wr_o : out std_logic; -- High pulse means store rx_dat_o.
- rx_done_o : out std_logic; -- Remains high after receive, until rx_restart_i
- frame_err_o : out std_logic; -- High = error. Reset when rx_restart_i asserted.
- parity_err_o : out std_logic -- High = error. Reset when rx_restart_i asserted.
- );
- end component;
-
-end uart_sqclk_pack;
-
-package body uart_sqclk_pack is
-end uart_sqclk_pack;
-
-
---------------------------------------------------------------------
--- UART. Variable Speed, RX Buffer, but no TX buffer
--- High Speed Asynchronous Receiver & Transmitter
---
--- Description:
--- This block receives and transmits asynchronous serial bytes. The Baudrate
--- and parity are selectable through inputs, but the number of bits per character
--- is fixed at eight.
---
--- NOTES:
--- Transmit starts when tx_wr_i is detected high at a rising clock edge.
--- Once the transmit operation is completed, tx_done_o latches high.
---
--- The receive input is passed through two layers of synchronizing flip-flops
--- to help mitigate metastability issues, since this signal can come from
--- outside of the sys_clk clock domain. All other logic connecting to inputs
--- of this function are assumed to be within the same clock domain.
---
--- The receiver looks for a new start bit immediately following the rx_wr_o
--- pulse, but rx_done_o is delayed until the expected end of the received
--- character. If a new start bit is detected just prior to the expected end
--- of the received character, then rx_done_o is not asserted.
---
--- Receive begins when the falling edge of the start bit is detected.
--- Then after 10 or 11 bit times have passed (depending on the parity setting)
--- the rx_wr_o signal will pulse high for one clock period, indicating rx_dat_o
--- contains valid receive data. The rx_wr_o pulse is only issued if there is
--- no parity error, and the stop bit is actually detected high at the sampling
--- time.
--- The rx_dat_o outputs will hold the received data until the next rx_wr_o pulse.
--- The rx_dat_o output provides the received data, even in the presence of a
--- parity or stop-bit error.
--- Error flags are valid during rx_wr_o, but they remain latched, until
--- rx_restart_i.
---
--- The Baud rate is equal to the frequency of the rate_clk_i input.
--- It should be, as nearly as possible, a square wave of the desired
--- communications rate.
---
-library IEEE;
-use IEEE.STD_LOGIC_1164.ALL;
-use IEEE.NUMERIC_STD.ALL;
-
-entity uart_sqclk is
- port (
-
- sys_rst_n : in std_logic;
- sys_clk : in std_logic;
- sys_clk_en : in std_logic;
-
- -- rate and parity
- parity_i : in unsigned(1 downto 0); -- 0=none, 1=even, 2 or 3=odd
- rate_clk_i : in std_logic;
-
- -- serial I/O
- tx_stream : out std_logic;
- rx_stream : in std_logic;
-
- --control and status
- tx_wr_i : in std_logic; -- Starts Transmit
- tx_dat_i : in unsigned(7 downto 0);
- tx_done_o : out std_logic;
- rx_restart_i : in std_logic; -- High clears error flags, clears rx_done_o
- rx_dat_o : out unsigned(7 downto 0);
- rx_wr_o : out std_logic; -- High pulse means store rx_dat_o.
- rx_done_o : out std_logic; -- Remains high after receive, until clk edge with rx_restart_i=1
- frame_err_o : out std_logic; -- High = error. Reset when rx_restart_i asserted.
- parity_err_o : out std_logic -- High = error. Reset when rx_restart_i asserted.
- );
-end uart_sqclk;
-
-library work;
-use work.uart_sqclk_pack.all;
-
-architecture beh of uart_sqclk is
-
--- Components
-
-begin
-
- tx1: async_tx_sqclk
- port map (
- sys_rst_n => sys_rst_n,
- sys_clk => sys_clk,
- sys_clk_en => sys_clk_en,
-
- -- rate and parity
- tx_parity_i => parity_i, -- 0=none, 1=even, 2 or 3=odd
- tx_clk_i => rate_clk_i,
-
- -- serial output
- tx_stream => tx_stream,
-
- -- control and status
- tx_wr_i => tx_wr_i, -- Starts Transmit
- tx_dat_i => tx_dat_i,
- tx_done_o => tx_done_o
- );
-
- rx1: async_rx_sqclk
- port map (
- sys_rst_n => sys_rst_n,
- sys_clk => sys_clk,
- sys_clk_en => sys_clk_en,
-
- -- rate and parity
- rx_parity_i => parity_i, -- 0=none, 1=even, 2 or 3=odd
- rx_clk_i => rate_clk_i,
-
- -- serial input
- rx_stream => rx_stream,
-
- -- control and status
- rx_restart_i => rx_restart_i, -- High clears error flags, clears rx_done_o
- rx_dat_o => rx_dat_o,
- rx_wr_o => rx_wr_o, -- High pulse means store rx_dat_o.
- rx_done_o => rx_done_o, -- Remains high after receive, until rx_restart_i
- frame_err_o => frame_err_o, -- High = error. Reset when rx_restart_i asserted.
- parity_err_o => parity_err_o -- High = error. Reset when rx_restart_i asserted.
- );
-
-end beh;
-
-
--------------------------------------------------------------------------------
--- Asynchronous Receiver With Output Buffer
--------------------------------------------------------------------------------
---
--- Author: John Clayton
--- Date : Aug 05, 2013 Added this change log header, which was missing.
--- Added first_edge signal to avoid erroneous initial
--- baud interval measurement (John Clayton & Philip
--- Kasavan)
--- Jan. 2, 2014 Added output buffer, changed idle_prep to include
--- the actual transition to IDLE state. Added
--- POST_RECV state, so that the rx_done_o signal will
--- reflect the true end of the received character.
--- This helps in applications where a received
--- asynchronous input is "echoed back" directly,
--- as the rx_wr_o signal can be used to switch the
--- signal at the correct time.
--- Feb. 6, 2014 Added requirement for half_baud to be non-zero
--- before leaving IDLE state. This prevents leaving
--- IDLE due to falling edges prior to the first Baud
--- interval measurement.
---
--- Description
--------------------------------------------------------------------------------
--- Squarewave tx_clk_i input determines rate.
--- (tx_clk_i does not really need to be a squarewave. Only the rising edges
--- are measured and used.)
---
--- Description:
--- This block receives asynchronous serial bytes. The Baudrate and parity
--- are determined by inputs, but the number of bits per character is
--- fixed at eight.
---
--- NOTES:
--- The receive input and baudrate clock are passed through two layers of
--- synchronizing flip-flops to mitigate metastability, since those signals can
--- originate outside of the sys_clk clock domain. All other logic connecting to
--- input of this function are assumed to be within the same clock domain.
---
--- The receiver looks for a new start bit immediately following the rx_wr_o
--- pulse, but rx_done_o is delayed until the expected end of the received
--- character. If a new start bit is detected just prior to the expected end
--- of the received character, then rx_done_o is not asserted.
---
--- Receive begins when the falling edge of the start bit is detected.
--- Then after 10 or 11 bit times have passed (depending on the parity setting)
--- the rx_wr_o signal will pulse high for one clock period, indicating rx_dat_o
--- contains valid receive data. The rx_wr_o pulse is only issued if there is
--- no parity error, and the stop bit is actually detected high at the sampling
--- time.
--- The rx_dat_o outputs will hold the received data until the next rx_wr_o pulse.
--- The rx_dat_o output provides the received data, even in the presence of a
--- parity or stop-bit error.
--- Error flags are valid during rx_wr_o, but they remain latched, until
--- rx_restart_i.
---
--- Although the receiver immediately restarts itself to receive the next
--- character, the rx_restart_i input can clear the error indicators. The rx_restart_i
--- input is like a synchronous reset in this respect since it will cause a receive
--- operation to abort.
---
-
-library IEEE;
-use IEEE.STD_LOGIC_1164.ALL;
-use IEEE.NUMERIC_STD.ALL;
-
-entity async_rx_sqclk is
- port (
-
- sys_rst_n : in std_logic;
- sys_clk : in std_logic;
- sys_clk_en : in std_logic;
-
- -- rate and parity
- rx_parity_i : in unsigned(1 downto 0); -- 0=none, 1=even, 2 or 3=odd
- rx_clk_i : in std_logic;
-
- -- serial input
- rx_stream : in std_logic;
-
- -- control and status
- rx_restart_i : in std_logic; -- High clears error flags, synchronously resets receiver
- rx_dat_o : out unsigned(7 downto 0);
- rx_wr_o : out std_logic; -- High pulse means store rx_dat_o.
- rx_done_o : out std_logic; -- Indicates receiver is idle
- frame_err_o : out std_logic; -- High = error. Reset when rx_restart_i asserted.
- parity_err_o : out std_logic -- High = error. Reset when rx_restart_i asserted.
- );
-end async_rx_sqclk;
-
-architecture beh of async_rx_sqclk is
-
-
--- RX signals
- -- rx_clk_i synchronizing flip-flops and rising edge detector
-signal rx_clk_r1 : std_logic;
-signal rx_clk_r2 : std_logic;
- -- RX input synchronizing flip flops
-signal rx_stream_r1 : std_logic;
-signal rx_stream_r2 : std_logic;
- -- RX signals
- -- RX State Machine
-type RX_STATE_TYPE is (IDLE, CHECK_START_1, CHECK_START_2, RECV_DATA, POST_RECV);
-signal rx_state : RX_STATE_TYPE;
-signal start_bit_start : std_logic; -- Signals falling edge of rx_stream_i
-signal rx_sr : unsigned(8 downto 0); -- Shift register
-signal rx_bcnt : unsigned(3 downto 0); -- Number of bits left, counts down
-signal rx_bcnt_start : unsigned(3 downto 0); -- Total number of bits
-signal rx_parity_good : std_logic;
- -- Timers have been sized to hold baud interval for speeds as slow as 9600 bps at 100MHz sys_clk
-signal rx_timer : unsigned(13 downto 0); -- Elapsed sys_clks from last bit time start
-signal half_baud : unsigned(13 downto 0); -- One half of full_baud
-signal full_baud : unsigned(13 downto 0); -- Baud interval, as measured from rx_clk_i
-signal baud_timer : unsigned(13 downto 0); -- Used to measure baud interval
-signal bit_sampled : std_logic; -- High indicates bit is already sampled, don't allow resampling.
-
-signal first_edge : std_logic;
-
-begin
-
- -- Synchronizing flip flops to avoid metastability issues...
- rx_stream_syncproc: Process(sys_rst_n,sys_clk)
- BEGIN
- if (sys_rst_n = '0') then
- rx_stream_r1 <= '1';
- rx_stream_r2 <= '1';
- elsif (sys_clk'event AND sys_clk='1') then
- if (sys_clk_en='1') then
- rx_stream_r2 <= rx_stream_r1;
- rx_stream_r1 <= rx_stream;
- end if;
- end if;
- END PROCESS rx_stream_syncproc;
--- start_bit_start <= rx_stream_r2 and not rx_stream_r1;
- -- This signal has been rewritten carefully to avoid "artifacts" which occur
- -- during simulation, when rx_stream_r1 is 'X', in a manner reminiscent of
- -- metastability.
- start_bit_start <= '1' when rx_stream_r2='1' and rx_stream_r1/='1' else '0';
-
- -- Synchronizing flip flops to avoid metastability issues...
- rx_clk_syncproc: Process(sys_rst_n,sys_clk)
- BEGIN
- if (sys_rst_n = '0') then
- rx_clk_r1 <= '0';
- rx_clk_r2 <= '0';
- elsif (sys_clk'event AND sys_clk='1') then
- if (sys_clk_en='1') then
- rx_clk_r2 <= rx_clk_r1;
- rx_clk_r1 <= rx_clk_i;
- end if;
- end if;
- END PROCESS rx_clk_syncproc;
-
- -- This is the baud interval measuring process.
- -- Measurements are only made between rising edges
- baud_measure_proc: Process(sys_rst_n,sys_clk)
- BEGIN
- if (sys_rst_n = '0') then
- full_baud <= (others=>'0');
- baud_timer <= (others=>'0');
- first_edge <= '0';
- elsif (sys_clk'event AND sys_clk='1') then
- if (sys_clk_en='1') then
- if(first_edge = '1')then
- if (rx_clk_r1='1' and rx_clk_r2='0') then
- full_baud <= baud_timer;
- baud_timer <= (others=>'0');
- else
- baud_timer <= baud_timer+1;
- end if;
- elsif(rx_clk_r1='1' and rx_clk_r2='0') then
- first_edge <= '1';
- end if;
- end if;
- end if;
- END PROCESS baud_measure_proc;
-
-
- -- This process handles the incoming bits
- uart_rx_bits: Process(sys_rst_n,sys_clk)
-
- procedure idle_prep is
- begin
- rx_done_o <= '1';
- bit_sampled <= '0';
- rx_bcnt <= (others=>'0');
- rx_timer <= (others=>'0');
- rx_state <= IDLE;
- end idle_prep;
-
- begin
- if (sys_rst_n = '0') then
- idle_prep;
- rx_sr <= (others=>'0');
- frame_err_o <= '0';
- parity_err_o <= '0';
- rx_wr_o <= '0';
- rx_dat_o <= (others=>'0');
- elsif (sys_clk'event AND sys_clk='1') then
- if (sys_clk_en='1') then
- -- Default values
- rx_wr_o <= '0'; -- Default to no data write
- -- Handle incrementing the sample timer
- rx_timer<=rx_timer+1;
- -- State transitions
- case rx_state is
-
- when IDLE =>
- rx_done_o <= '1'; -- Indicate receive is done.
- bit_sampled <= '0'; -- Indicate bit is not yet sampled.
- if (rx_restart_i='1') then
- idle_prep;
- frame_err_o <= '0'; -- At rx_restart, also clear error flags
- parity_err_o <= '0';
- elsif (half_baud/=0 and start_bit_start='1') then
- rx_timer <= (others=>'0'); -- Reset timer back to zero
- rx_bcnt <= rx_bcnt_start; -- Initialize bit counter
- rx_done_o <= '0';
- rx_state <= CHECK_START_1;
- end if;
-
- when CHECK_START_1 =>
- if (rx_restart_i='1') then -- Restart has very high priority
- idle_prep;
- elsif (rx_stream_r2='1') then -- High during this time is an error
- frame_err_o <= '1';
- idle_prep;
- elsif (rx_timer>=half_baud) then -- Must use >= since threshold may change downward
- rx_state <= CHECK_START_2;
- end if;
-
- when CHECK_START_2 => -- During second half of start bit, don't verify low level
- if (rx_restart_i='1') then -- Restart has very high priority
- idle_prep;
- elsif (rx_timer>=full_baud or rx_stream_r2='1') then -- Wait for end of start bit
- rx_timer <= (others=>'0'); -- Reset timer back to zero
- rx_state <= RECV_DATA;
- end if;
-
- when RECV_DATA =>
- if (rx_restart_i='1') then -- Restart has very high priority
- idle_prep;
- elsif (rx_timer>=full_baud) then -- Must use >= since threshold may change downward
- rx_timer <= (others=>'0'); -- Reset timer back to zero
- bit_sampled <= '0';
- elsif (rx_timer>=half_baud and bit_sampled='0') then -- Must use >= since threshold may change downward
- bit_sampled <= '1';
- if (rx_bcnt="0000") then
- rx_state <= POST_RECV;
- rx_dat_o <= rx_sr(7 downto 0);
- if (rx_parity_good='1' and rx_stream_r2='1') then
- rx_wr_o <= '1'; -- If all is correct, create a one clock long pulse to store rx_dat_o.
- else
- if (rx_stream_r2='0') then
- frame_err_o <= '1'; -- Record error if there is a bad stop bit
- end if;
- if (rx_parity_good='0') then
- parity_err_o <= '1'; -- Record error if there is bad parity
- end if;
- end if;
- else -- Process a new bit
- rx_sr(7 downto 0) <= rx_sr(8 downto 1);
- if (rx_parity_i = "00") then
- rx_sr(7) <= rx_stream_r2; -- Store the new incoming bit
- else
- rx_sr(8) <= rx_stream_r2;
- end if;
- rx_bcnt <= rx_bcnt-1;
- end if;
- end if;
-
- when POST_RECV => -- Wait out latter half of stop bit, checking for start bits...
- if (rx_restart_i='1') then
- bit_sampled <= '0';
- frame_err_o <= '0'; -- At rx_restart, also clear error flags
- parity_err_o <= '0';
- idle_prep;
- elsif (start_bit_start='1') then
- bit_sampled <= '0';
- rx_timer <= (others=>'0'); -- Reset timer back to zero
- rx_bcnt <= rx_bcnt_start; -- Initialize bit counter
- rx_done_o <= '0';
- rx_state <= CHECK_START_1;
- elsif (rx_timer>=full_baud) then -- Wait for end of start bit
- bit_sampled <= '0'; -- Indicate bit is not yet sampled.
- idle_prep; -- Asserts rx_done_o to indicate completion
- end if;
-
- when others => null;
-
- end case;
- end if;
- end if;
- end process uart_rx_bits;
-
- -------------------------
- -- Assign number of bits to shift in.
- rx_bcnt_start <= "1000" when (rx_parity_i="00") else "1001";
-
- -------------------------
- -- Assign half baud period
- half_baud <= ('0' & full_baud(13 downto 1));
-
- -------------------------
- -- Parity check process
- rx_parity_check: process(rx_sr, rx_parity_i)
- begin
- if (rx_parity_i="00") then -- No parity...
- rx_parity_good <= '1'; -- (always good.)
- elsif (rx_parity_i="01") then -- Even parity...
- rx_parity_good <= not (rx_sr(0) XOR rx_sr(1) XOR rx_sr(2) XOR rx_sr(3) XOR rx_sr(4)
- XOR rx_sr(5) XOR rx_sr(6) XOR rx_sr(7) XOR rx_sr(8));
- else -- Odd parity...
- rx_parity_good <= (rx_sr(0) XOR rx_sr(1) XOR rx_sr(2) XOR rx_sr(3) XOR rx_sr(4)
- XOR rx_sr(5) XOR rx_sr(6) XOR rx_sr(7) XOR rx_sr(8));
- end if;
- end process;
-
-end beh;
-
-
--------------------------------------------------------------------------------
--- Asynchronous Transmitter With No Buffering
--------------------------------------------------------------------------------
---
--- Author: John Clayton
--- Date : Aug 08, 2013 Added this change log header, which was missing.
--- Changed tx_done_o signal so that it pulses after
--- the stop bit is finished. How could this have
--- remained so woefully incorrect for so long?!
--- Jan 02, 2014 Fixed a latent bug in the logic for asserting
--- tx_done_o. Prior to this fix, it was possible
--- for a write that was coincident with do_txbit to
--- be ignored! Once again, how could this have
--- remained so woefully incorrect all this time?!
--- Jan 07, 2014 Rewrote the startup logic to allow for cases
--- when tx_wr_i='1' and tx_bcnt="0000" and do_txbit='1'
--- Also rewrote the tx_done_o signal so that it is
--- asserted earlier - when "tx_almost_done" is high.
--- This is all calculated to allow the transmitter
--- to send characters back-to-back using its own
--- tx_done_o signal as a tx_wr_i signal. This is
--- actually getting pretty neat. The unit sends out
--- asynchronous characters, but insists on doing it
--- in synchronism with the tx_clk_i input... so it
--- isn't really very asynchronous in that sense!
---
--- Description
--------------------------------------------------------------------------------
--- Squarewave tx_clk_i input determines rate.
--- (tx_clk_i need not be a squarewave for this module, since only the rising
--- edge is used. In the accompanying receiver, however, both edges are used.)
---
--- Description:
--- This block transmits asynchronous serial bytes. The Baudrate and parity
--- are determined by inputs, but the number of bits per character is
--- fixed at eight.
---
--- NOTES:
--- Transmit starts when the transmitter is idle and tx_wr_i is detected high
--- at a rising sys_clk edge.
---
--- Once the transmit operation is completed, done_o latches high.
---
--- Since the baud clock might be asynchronous to the sys_clk, there are
--- syncronizing flip-flops on it inside this module.
-
-library IEEE;
-use IEEE.STD_LOGIC_1164.ALL;
-use IEEE.NUMERIC_STD.ALL;
-
-entity async_tx_sqclk is
- port (
-
- sys_rst_n : in std_logic;
- sys_clk : in std_logic;
- sys_clk_en : in std_logic;
-
- -- rate and parity
- tx_parity_i : in unsigned(1 downto 0); -- 0=none, 1=even, 2 or 3=odd
- tx_clk_i : in std_logic;
-
- -- serial output
- tx_stream : out std_logic;
-
- -- control and status
- tx_wr_i : in std_logic; -- Starts Transmit
- tx_dat_i : in unsigned(7 downto 0);
- tx_done_o : out std_logic
- );
-end async_tx_sqclk;
-
-architecture beh of async_tx_sqclk is
-
--- TX signals
- -- TX clock synchronizing flip-flops and rising edge detection
-signal tx_clk_r1 : std_logic;
-signal tx_clk_r2 : std_logic;
- -- TX clock enable, shift register and bit count
-signal do_txbit : std_logic;
-signal tx_sr : unsigned(9 downto 0);
-signal tx_bcnt : unsigned(3 downto 0); -- Number of bits
-signal tx_almost_done : std_logic;
-signal tx_done : std_logic;
-
-begin
-
- -- This process detects the rising edge of tx_clk_i
- tx_clk_edge_proc: Process(sys_rst_n,sys_clk)
- BEGIN
- if (sys_rst_n = '0') then
- tx_clk_r1 <= '0';
- tx_clk_r2 <= '0';
- elsif (sys_clk'event AND sys_clk='1') then
- if (sys_clk_en='1') then
- tx_clk_r1 <= tx_clk_i;
- tx_clk_r2 <= tx_clk_r1;
- end if;
- end if;
- END PROCESS tx_clk_edge_proc;
- do_txbit <= (tx_clk_r1 and not tx_clk_r2); -- rising edge detect
-
- -- This process loads the shift register, then counts as the bits transmit out.
- byte_tx: Process(sys_rst_n,sys_clk)
- BEGIN
- if (sys_rst_n = '0') then
- tx_sr <= (others=>'0');
- tx_bcnt <= (others=>'0');
- tx_stream <= '1';
- tx_done <= '1';
- elsif (sys_clk'event and sys_clk='1') then
- if (sys_clk_en='1') then
- -- Start a new transmission when ready
- -- Case 1 is starting while do_txbit is high
- if tx_bcnt="0000" and do_txbit='1' and tx_wr_i='1' then
- tx_stream <= '0'; -- Provide start bit
- tx_sr(7 downto 0) <= tx_dat_i; -- Load the TX data
- tx_sr(8) <= '1'; -- Default the parity bit to one
- if(tx_parity_i = "00") then --If no parity...
- tx_bcnt <= "1001"; -- send start, 8 data bits, and stop
- elsif (tx_parity_i = "01") then --If even parity...
- tx_bcnt <= "1010"; -- send start, 8 data bits, parity, and stop
- tx_sr(8) <= tx_dat_i(0) XOR tx_dat_i(1) XOR tx_dat_i(2) XOR tx_dat_i(3) XOR
- tx_dat_i(4) XOR tx_dat_i(5) XOR tx_dat_i(6) XOR tx_dat_i(7);
- else --If odd parity...
- tx_bcnt <= "1011"; --send start, 8 data bits, parity, and stop
- tx_sr(8) <= NOT (tx_dat_i(0) XOR tx_dat_i(1) XOR tx_dat_i(2) XOR tx_dat_i(3) XOR
- tx_dat_i(4) XOR tx_dat_i(5) XOR tx_dat_i(6) XOR tx_dat_i(7));
- end if;
- tx_done <= '0';
- -- Case 2 is starting while do_txbit is low
- elsif tx_done='1' and tx_wr_i='1' then -- Only allow loads when transmitter is idle
- tx_sr(0) <= '0'; -- Load start bit
- tx_sr(8 downto 1) <= tx_dat_i; -- Load the TX data
- tx_sr(9) <= '1'; -- Default the parity bit to one
- if(tx_parity_i = "00") then --If no parity...
- tx_bcnt <= "1010"; -- send start, 8 data bits, and stop
- elsif (tx_parity_i = "01") then --If even parity...
- tx_bcnt <= "1011"; -- send start, 8 data bits, parity, and stop
- tx_sr(9) <= tx_dat_i(0) XOR tx_dat_i(1) XOR tx_dat_i(2) XOR tx_dat_i(3) XOR
- tx_dat_i(4) XOR tx_dat_i(5) XOR tx_dat_i(6) XOR tx_dat_i(7);
- else --If odd parity...
- tx_bcnt <= "1011"; --send start, 8 data bits, parity, and stop
- tx_sr(9) <= NOT (tx_dat_i(0) XOR tx_dat_i(1) XOR tx_dat_i(2) XOR tx_dat_i(3) XOR
- tx_dat_i(4) XOR tx_dat_i(5) XOR tx_dat_i(6) XOR tx_dat_i(7));
- end if;
- tx_done <= '0';
- -- Process through the remaining data
- elsif(tx_bcnt>"0000" and do_txbit='1') then -- Still have bits to send?
- tx_bcnt <= tx_bcnt-1;
- tx_sr(8 downto 0) <= tx_sr(9 downto 1); -- Right shift the data (send LSB first)
- tx_sr(9) <= '1';
- tx_stream <= tx_sr(0);
- end if;
- -- Assert tx_done when truly finished.
- if tx_almost_done='1' and tx_wr_i='0' then
- tx_done <= '1';
- end if;
- end if; -- sys_clk_en
- end if; -- sys_clk'event...
- END PROCESS byte_tx;
-
- tx_almost_done <= '1' when (tx_done='0' and tx_bcnt="0000" and do_txbit='1') else '0';
- tx_done_o <= '1' when tx_done='1' or tx_almost_done='1' else '0';
-
-end beh;
-
-
Index: rs232_syscon/trunk/VHDL/async_syscon_pack.vhd
===================================================================
--- rs232_syscon/trunk/VHDL/async_syscon_pack.vhd (revision 8)
+++ rs232_syscon/trunk/VHDL/async_syscon_pack.vhd (nonexistent)
@@ -1,1240 +0,0 @@
---------------------------------------------------------------------------
--- Package of async_syscon components
---
-
-library IEEE;
-use IEEE.STD_LOGIC_1164.ALL;
-use IEEE.NUMERIC_STD.ALL;
-
-package async_syscon_pack is
-
- -- A system controller with an 8-bit parallel ASCII interface
- component ascii_syscon
- generic (
- ADR_DIGITS : natural; -- # of hex digits for address
- DAT_DIGITS : natural; -- # of hex digits for data
- QTY_DIGITS : natural; -- # of hex digits for quantity
- CMD_BUFFER_SIZE : natural; -- # of chars in the command buffer
- WATCHDOG_VALUE : natural; -- # of sys_clks before ack is expected
- DISPLAY_FIELDS : natural -- # of fields/line
- );
- port (
-
- sys_rst_n : in std_logic;
- sys_clk : in std_logic;
- sys_clk_en : in std_logic;
-
- -- Parallel ASCII I/O
- cmd_char_i : in unsigned(7 downto 0);
- cmd_we_i : in std_logic;
- cmd_ack_o : out std_logic;
- cmd_echo_o : out std_logic;
- resp_char_o : out unsigned(7 downto 0);
- resp_cyc_o : out std_logic;
- resp_ack_i : in std_logic;
- cmd_done_o : out std_logic;
-
- -- Master Bus IO
- master_bg_i : in std_logic;
- master_adr_i : in unsigned(4*ADR_DIGITS-1 downto 0);
- master_dat_i : in unsigned(4*DAT_DIGITS-1 downto 0);
- master_dat_o : out unsigned(4*DAT_DIGITS-1 downto 0);
- master_stb_i : in std_logic;
- master_we_i : in std_logic;
- master_br_o : out std_logic;
-
- -- System Bus IO
- ack_i : in std_logic;
- err_i : in std_logic;
- dat_i : in unsigned(4*DAT_DIGITS-1 downto 0);
- dat_o : out unsigned(4*DAT_DIGITS-1 downto 0);
- rst_o : out std_logic;
- stb_o : out std_logic;
- cyc_o : out std_logic;
- adr_o : out unsigned(4*ADR_DIGITS-1 downto 0);
- we_o : out std_logic
- );
- end component;
-
- -- ascii_syscon mounted with a UART interface
- component async_syscon
- generic (
- ECHO_COMMANDS : natural; -- set nonzero to echo back command characters
- ADR_DIGITS : natural; -- # of hex digits for address
- DAT_DIGITS : natural; -- # of hex digits for data
- QTY_DIGITS : natural; -- # of hex digits for quantity
- CMD_BUFFER_SIZE : natural; -- # of chars in the command buffer
- WATCHDOG_VALUE : natural; -- # of sys_clks before ack is expected
- DISPLAY_FIELDS : natural -- # of fields/line
- );
- port (
-
- sys_rst_n : in std_logic;
- sys_clk : in std_logic;
- sys_clk_en : in std_logic;
-
- -- rate and parity
- parity_i : in unsigned(1 downto 0); -- 0=none, 1=even, 2=odd
- baud_clk_i : in std_logic; -- At 1x the desired baud rate, can be squarewave or pulses.
- baud_lock_i : in std_logic; -- '1' Indicates baud clock is stable and ready.
-
- -- Serial IO
- cmd_i : in std_logic;
- resp_o : out std_logic;
- cmd_done_o : out std_logic;
-
- -- Master Bus IO
- master_bg_i : in std_logic;
- master_adr_i : in unsigned(4*ADR_DIGITS-1 downto 0);
- master_dat_i : in unsigned(4*DAT_DIGITS-1 downto 0);
- master_dat_o : out unsigned(4*DAT_DIGITS-1 downto 0);
- master_stb_i : in std_logic;
- master_we_i : in std_logic;
- master_br_o : out std_logic;
-
- -- System Bus IO
- ack_i : in std_logic;
- err_i : in std_logic;
- dat_i : in unsigned(4*DAT_DIGITS-1 downto 0);
- dat_o : out unsigned(4*DAT_DIGITS-1 downto 0);
- rst_o : out std_logic;
- stb_o : out std_logic;
- cyc_o : out std_logic;
- adr_o : out unsigned(4*ADR_DIGITS-1 downto 0);
- we_o : out std_logic
- );
- end component;
-
-end async_syscon_pack;
-
-package body async_syscon_pack is
-end async_syscon_pack;
-
----------------------------------------------------------------------------------------
---
--- Author: John Clayton
--- Date : Dec. 27, 2013
--- Update: 12/27/13 copied async_syscon module, removed the serial interface.
--- 02/05/14 Added line feed as a whitespace character, to
--- char_is_whitespace.
--- 02/06/14 Made resp_cyc a direct function of the state machine state.
--- This allows it to be asserted even when resp_ack_i is tied
--- to '1' all the time...
--- 02/13/14 Made a slight enhancement to the processing of comments.
--- Previously, all comments were treated as "full line"
--- comments, causing any valid commands preceding the
--- comment to be ignored, since the entire line was being
--- ignored. I realized that a very small value
--- check on cmd_ptr could differentiate between full line
--- comments, and ones for which there might actually be
--- a valid command. The enhanced design can process the
--- valid commands.
--- 02/14/14 Happy Valentine's Day! Fixed a "wacky" bug which caused
--- an extra digit to be displayed for address and data fields.
--- Added "0" command suffix, which prevents the bus address
--- from incrementing during read, write and fill operations.
--- It's useful for working with FIFOs that have read/write
--- ports mapped to a single address, instead of a whole
--- range of addresses.
--- 02/27/14 Refined the CHECK_SUFFICES state by adding a jump to
--- START_EXECUTION when ENTER_CHAR is found in the suffix
--- position, thus preserving the "repeat last read with
--- previous address and quantity" function.
---
--- Description
----------------------------------------------------------------------------------------
--- This is an 8-bit parallel ASCII character driven interface to a system
--- controller driving a "Wishbone" type of parallel system bus.
---
--- Specifically, the unit allows the user to send text commands to the
--- "ascii_syscon" unit, in order to generate read and write cycles on the
--- Wishbone compatible bus. The command structure is quite terse and spartan
--- in nature, this is for the sake of the logic itself.
---
--- The command line buffer is small enough to be implemented without the use
--- of dedicated BRAM memory blocks, and the menus and command responses were
--- kept as small as possible. In most cases, the responses from the unit to
--- the user consist of a "newline" and one or two visible characters. The
--- command structure consists of the following commands and responses:
---
--- Command Syntax Purpose
--- --------------- ---------------------------------------
--- w aaaa dddd dddd dddd... Write data items "dddd" starting at address "aaaa"
--- using sequential addresses.
--- (If the data field is missing, nothing is done).
--- w0 aaaa dddd dddd dddd... Write data items "dddd" at address "aaaa"
--- without incrementing the address.
--- (If the data field is missing, nothing is done).
--- f aaaa dddd xx "Fill": Write data "dddd" starting at address "aaaa"
--- perform this "xx" times at sequential addresses.
--- (The quantity field is optional, default is 1).
--- f0 aaaa dddd xx "Fill": Write data "dddd" starting at address "aaaa"
--- perform this "xx" times at the same address.
--- (The quantity field is optional, default is 1).
--- r aaaa xx Read data starting from address "aaaa."
--- Perform this "xx" times at sequential addresses.
--- (The quantity field is optional, default is 1).
--- r0 aaaa xx Read data from address "aaaa."
--- Perform this "xx" times, using the same address.
--- (The quantity field is optional, default is 1).
--- i Send a reset pulse to the system. (initialize).
---
--- "Single Line" type Comment token. Characters
--- after the token are ignored until .
--- This enables applications which send
--- files to the unit to include comments for
--- display and as an aid to understanding.
--- The comment token is a constant, change it
--- to be whatever makes sense!
---
--- Response from async_syscon Meaning
--- -------------------------- ---------------------------------------
--- OK Command received and performed. No errors.
--- ? Command buffer full, without receiving "enter."
--- C? Command not recognized.
--- A? Address field syntax error.
--- D? Data field syntax error.
--- Q? Quantity field syntax error.
--- ! No "ack_i", or else "err_i" received from bus.
--- B! No "bg_i" received from master.
---
--- NOTES on the operation of this unit:
---
--- - The unit generates a command prompt which is "-> ".
--- - Capitalization is not important.
--- - Each command is terminated by the "enter" key (0x0d character).
--- Commands are executed as soon as "enter" is received.
--- - Trailing parameters need not be re-entered. Their values will
--- remain the same as their previous settings.
--- - Use of the backspace key is supported, so mistakes can be corrected.
--- - The length of the command line is limited to a fixed number of
--- characters, as configured by parameter.
--- - Fields are separated by white space, including "tab" and/or "space"
--- - All numerical fields are interpreted as hexadecimal numbers.
--- Decimal is not supported.
--- - Numerical field values are retained between commands. If a "r" is issued
--- without any fields following it, the previous values will be used. A
--- set of "quantity" reads will take place at sequential addresses.
--- If a "f" is issued without any fields following it, the previous data
--- value will be written "quantity" times at sequential addresses, starting
--- from the next location beyond where the last command ended.
--- - If the user does not wish to use "ack" functionality, simply tie the
--- "ack_i" input to logic 1, and then the ! response will never be generated.
--- - The data which is read in by the "r" command is displayed using lines
--- which begin with the address, followed by the data fields. The number
--- of data fields displayed per line (following the address) is adjustable
--- by setting a parameter. No other display format adjustments can be made.
--- - There is currently only a single watchdog timer. It begins to count at
--- the time the "enter" is received to execute a command. If the bus is granted
--- and the ack is received before the expiration of the timer, then the
--- cycle will complete normally. Therefore, the watchdog timeout value
--- needs to include time for the request and granting of the bus, in
--- addition to the time needed for the actual bus cycle to complete.
---
---
--- Currently, there is only a single indicator (stb_o) generated during bus
--- output cycles which are generated from this unit.
--- The user can easily implement decoding logic based upon adr_o and stb_o
--- which would serve as multiple "stb_o" type signals for different cores
--- which would be sharing the same bus.
---
--- The data bus supported by this module is separate input/output type of bus.
--- However, if a single tri-state dat_io bus is desired, it can be added
--- to the module without too much trouble. Supposedly the only difference
--- between the two forms of data bus is that one of them avoids using tri-state
--- at the cost of doubling the number of interconnects used to carry data back
--- and forth... Some people say that tri-state should be avoided for use
--- in internal busses in ASICs. Maybe they are right.
--- But in FPGAs tri-state seems to work pretty well, even for internal busses.
---
--- Parameters are provided to configure the width of the different command
--- fields. To simplify the logic for binary to hexadecimal conversion, these
--- parameters allow adjustment in units of 1 hex digit, not anything smaller.
--- If your bus has 10 bits, for instance, simply set the address width to 3
--- which produces 12 bits, and then just don't use the 2 msbs of address
--- output.
---
--- No support for the optional Wishbone "retry" (rty_i) input is provided at
--- this time.
--- No support for "tagn_o" bits is provided at this time, although a register
--- might be added external to this module in order to implement to tag bits.
--- No BLOCK or RMW cycles are supported currently, so cyc_o is equivalent to
--- stb_o...
--- The output busses are not tri-stated. The user may add tri-state buffers
--- external to the module, using "stb_o" to enable the buffer outputs.
---
----------------------------------------------------------------------------------------
-
-library IEEE;
-use IEEE.STD_LOGIC_1164.ALL;
-use IEEE.NUMERIC_STD.ALL;
-
-library work;
-use work.function_pack.all;
-use work.async_syscon_pack.all;
-
-entity ascii_syscon is
- generic (
- ADR_DIGITS : natural := 4; -- # of hex digits for address
- DAT_DIGITS : natural := 4; -- # of hex digits for data
- QTY_DIGITS : natural := 2; -- # of hex digits for quantity
- CMD_BUFFER_SIZE : natural := 32; -- # of chars in the command buffer
- WATCHDOG_VALUE : natural := 200; -- # of sys_clks before ack is expected
- DISPLAY_FIELDS : natural := 8 -- # of fields/line
- );
- port (
-
- sys_rst_n : in std_logic;
- sys_clk : in std_logic;
- sys_clk_en : in std_logic;
-
- -- Parallel ASCII I/O
- cmd_char_i : in unsigned(7 downto 0);
- cmd_we_i : in std_logic;
- cmd_ack_o : out std_logic;
- cmd_echo_o : out std_logic;
- resp_char_o : out unsigned(7 downto 0);
- resp_cyc_o : out std_logic;
- resp_ack_i : in std_logic;
- cmd_done_o : out std_logic;
-
- -- Master Bus IO
- master_bg_i : in std_logic;
- master_adr_i : in unsigned(4*ADR_DIGITS-1 downto 0);
- master_dat_i : in unsigned(4*DAT_DIGITS-1 downto 0);
- master_dat_o : out unsigned(4*DAT_DIGITS-1 downto 0);
- master_stb_i : in std_logic;
- master_we_i : in std_logic;
- master_br_o : out std_logic;
-
- -- System Bus IO
- ack_i : in std_logic;
- err_i : in std_logic;
- dat_i : in unsigned(4*DAT_DIGITS-1 downto 0);
- dat_o : out unsigned(4*DAT_DIGITS-1 downto 0);
- rst_o : out std_logic;
- stb_o : out std_logic;
- cyc_o : out std_logic;
- adr_o : out unsigned(4*ADR_DIGITS-1 downto 0);
- we_o : out std_logic
- );
-end ascii_syscon;
-
-library IEEE;
-use IEEE.STD_LOGIC_1164.ALL;
-use IEEE.NUMERIC_STD.ALL;
-
-architecture beh of ascii_syscon is
-
--- Constants
-constant CMD_PTR_BITS : natural := bit_width(CMD_BUFFER_SIZE);
-constant DISPLAY_FIELD_COUNT_BITS : natural := bit_width(DISPLAY_FIELDS);
-constant DISPLAY_ADR_DIGIT_COUNT_BITS : natural := bit_width(ADR_DIGITS);
-constant DISPLAY_DAT_DIGIT_COUNT_BITS : natural := bit_width(DAT_DIGITS);
-constant WATCHDOG_TIMER_BITS : natural := timer_width(WATCHDOG_VALUE);
-
-constant BACKSPACE_CHAR : unsigned := "00001000";
-constant ENTER_CHAR : unsigned := "00001101";
-constant COMMENT_CHAR : unsigned := "00100011"; -- '#' character
---constant COMMENT_CHAR : unsigned := "00101101"; -- '-' character
-
--- Internal signal declarations
- -- For the state machine
-type FSM_STATE_TYPE is (IDLE, SEND_WELCOME_STRING, SEND_OK, SEND_PROMPT,
- CHECK_NEW_CHAR, SEND_CRLF, PARSE_ERR_INDICATOR_CRLF,
- ERR_INDICATOR, BG_ERR_INDICATOR, SEND_QUESTION,
- SCAN_CMD, CHECK_SUFFICES, SCAN_ADR_WHITESPACE,
- GET_ADR_FIELD, SCAN_DAT_WHITESPACE, GET_DAT_FIELD,
- SCAN_QTY_WHITESPACE, GET_QTY_FIELD, START_EXECUTION,
- REQUEST_BUS, EXECUTE, DISPLAY_PREP, DISPLAY_ADR,
- DISPLAY_SEPARATOR, DISPLAY_DAT, DISPLAY_SPACE,
- DISPLAY_CRLF, POST_FILL_CYCLE);
-
-signal fsm_state : FSM_STATE_TYPE;
-
-signal watchdog_timer_done : std_logic; -- High when watchdog timer is expired
-signal char_is_whitespace : std_logic; -- High when cmd_buffer[char_count] is whitespace.
-signal char_is_num : std_logic; -- High when cmd_buffer[char_count] is 0..9
-signal char_is_a_f : std_logic; -- High when cmd_buffer[char_count] is a..f
-signal char_is_hex : std_logic; -- High when cmd_buffer[char_count] is a hex char.
-signal msg_pointer : unsigned(4 downto 0); -- Determines message position or address.
-signal msg_select : unsigned(4 downto 0); -- selection of msg_pointer or display value
-signal hex_digit : unsigned(3 downto 0); -- This is the digit to be stored.
-
-signal msg_char : unsigned(7 downto 0); -- Selected response message character.
-signal comment_area : std_logic;
-
- -- For the buses
-signal adr_ptr : unsigned(4*ADR_DIGITS-1 downto 0); -- = adr_sr + adr_offset
-
-signal stb_l : std_logic; -- "local" stb signal (to distinguish from stb_o)
-signal we_l : std_logic; -- "local" we signal (to distinguish from we_o)
-
-signal display_adr_sr : unsigned(4*ADR_DIGITS-1 downto 0); -- sr for printing addresses
-signal adr_sr : unsigned(4*ADR_DIGITS-1 downto 0); -- "nibble" shift register
-signal dat_sr : unsigned(4*DAT_DIGITS-1 downto 0); -- "nibble" shift register
-signal qty_sr : unsigned(4*QTY_DIGITS-1 downto 0); -- "nibble" shift register
-
--- The command register has these values
-type CMD_REG_TYPE is (INIT, READ, FILL, WRITE);
-signal command : CMD_REG_TYPE;
-
- -- For the command buffer
-signal cmd_ptr : unsigned(CMD_PTR_BITS-1 downto 0); -- Offset from start of command.
---signal rd_cmd_ptr : unsigned(CMD_PTR_BITS-1 downto 0); -- Latched cmd_ptr, use to infer BRAM.
-type cmd_array_type is
- array (integer range 0 to CMD_BUFFER_SIZE-1) of unsigned(7 downto 0);
-
-signal cmd_buffer : cmd_array_type;
-signal cmd_char : unsigned(7 downto 0);
-signal lc_cmd_char : unsigned(7 downto 0); -- Lowercase version of cmd_char
-signal adr_offset : unsigned(4*QTY_DIGITS-1 downto 0); -- counts from 0 to qty_sr
-signal adr_freeze : std_logic; -- When set, prevents adr_offset from incrementing
-
-signal resp_cyc : std_logic; -- high for response type states
-signal resp_cyc_l : std_logic;
-signal resp_cyc_mask : std_logic; -- Used to lower resp_cyc_o for one clock cycle, upon acknowledgement.
-
- -- For various counters
-signal display_field_count : unsigned(DISPLAY_FIELD_COUNT_BITS-1 downto 0); -- "fields displayed"
-signal display_adr_digit_count : unsigned(DISPLAY_ADR_DIGIT_COUNT_BITS-1 downto 0); -- "digits displayed"
-signal display_dat_digit_count : unsigned(DISPLAY_DAT_DIGIT_COUNT_BITS-1 downto 0); -- "digits displayed"
-signal watchdog_timer_count : unsigned(WATCHDOG_TIMER_BITS-1 downto 0);
-
-----------------------------------------------------------------------------
--- Component Declarations
-----------------------------------------------------------------------------
-
-----------------------------------------------------------------------------
-begin
-
--- In this module, command characters are accepted immediately but only when in the CHECK_NEW_CHAR state.
-cmd_ack_o <= '1' when cmd_we_i='1' and fsm_state=CHECK_NEW_CHAR else '0';
-
--- Provide response character cycle active signal
-resp_cyc <= '1' when fsm_state=DISPLAY_CRLF or
- fsm_state=DISPLAY_SPACE or
- fsm_state=DISPLAY_DAT or
- fsm_state=DISPLAY_SEPARATOR or
- fsm_state=DISPLAY_ADR or
- fsm_state=SEND_QUESTION or
- fsm_state=ERR_INDICATOR or
- fsm_state=PARSE_ERR_INDICATOR_CRLF or
- fsm_state=BG_ERR_INDICATOR or
- fsm_state=SEND_CRLF or
- fsm_state=SEND_PROMPT or
- fsm_state=SEND_OK or
- fsm_state=SEND_WELCOME_STRING else
- '0';
--- Implement the "courtesy" of lowering resp_cyc_o for one cycle after resp_ack_i is recognized.
--- This increases the amount of time needed for data transfer, and some would say it is needless,
--- since a "burst" type transfer also can work. Since burst transfers were not intended here,
--- this is being done anyway. You see, burst transfers can "tie up" bus arbiters for the entire
--- burst, which is not desirable in this design.
-resp_cyc_l <= '1' when resp_cyc='1' and resp_cyc_mask='0' else '0';
-resp_cyc_o <= resp_cyc_l;
-
-resp_cyc_mask_proc : process(sys_clk,sys_rst_n)
-variable i : natural;
-begin
- if (sys_rst_n='0') then
- resp_cyc_mask <= '0';
- elsif (sys_clk'event and sys_clk='1') then
- if (sys_clk_en='1') then
- resp_cyc_mask <= '0'; -- Default value
- if (resp_cyc_l='1' and resp_ack_i='1') then
- resp_cyc_mask <= '1';
- end if;
- end if;
- end if;
-end process;
-
-
--- Provide command echo indication, to allow ASCII response data to be
--- echoed or not, as desired.
-cmd_echo_o <= '1' when fsm_state=CHECK_NEW_CHAR else '0';
-
--- Provide parallel ASCII response data
-resp_char_o <= msg_char;
-
--- Select which bus signals get used on the system bus
-adr_o <= adr_ptr when (master_bg_i='1') else master_adr_i;
-we_o <= we_l when (master_bg_i='1') else master_we_i;
-stb_o <= stb_l when (master_bg_i='1') else master_stb_i;
-cyc_o <= stb_l when (master_bg_i='1') else master_stb_i; -- Separate cyc_o is not yet supported!
-
-dat_o <= dat_sr when (master_bg_i='1' and we_l='1' and stb_l='1') else master_dat_i;
-master_dat_o <= dat_i;
-
--- This forms the adress pointer which is used on the bus.
-adr_ptr <= adr_sr + adr_offset when adr_freeze='0' else adr_sr;
-
--- This is the ROM for the ASCII characters to be transmitted.
--- Choose which value to use
-msg_select <= '0' & display_adr_sr(4*ADR_DIGITS-1 downto 4*(ADR_DIGITS-1)) when fsm_state=DISPLAY_ADR else
- '0' & dat_sr(4*DAT_DIGITS-1 downto 4*(DAT_DIGITS-1)) when fsm_state=DISPLAY_DAT else
- msg_pointer;
-with (msg_select) select
- msg_char <=
- "00110000" when "00000", -- "0"; -- Hexadecimal characters
- "00110001" when "00001", -- "1";
- "00110010" when "00010", -- "2";
- "00110011" when "00011", -- "3";
- "00110100" when "00100", -- "4";
- "00110101" when "00101", -- "5";
- "00110110" when "00110", -- "6";
- "00110111" when "00111", -- "7";
- "00111000" when "01000", -- "8";
- "00111001" when "01001", -- "9";
- "01000001" when "01010", -- "A"; -- Address error indication
- "01000010" when "01011", -- "B";
- "01000011" when "01100", -- "C"; -- Command error indication
- "01000100" when "01101", -- "D"; -- Data error indication
- "01000101" when "01110", -- "E";
- "01000110" when "01111", -- "F";
- "00100000" when "10000", -- " "; -- Space
- "00111010" when "10001", -- ":"; -- Colon
- "00100000" when "10010", -- " "; -- Space
- "00111111" when "10011", -- "?"; -- Parse error indication
- "00100001" when "10100", -- "!"; -- ack_i/err_i error indication
- "01001111" when "10101", -- "O"; -- "All is well" message
- "01001011" when "10110", -- "K";
- "00001101" when "10111", -- Carriage Return
- "00001010" when "11000", -- Line Feed
- "00101101" when "11001", -- "-"; -- Command Prompt
- "00111110" when "11010", -- ">";
- "00100000" when "11011", -- " ";
- "01010001" when "11100", -- "Q"; -- Quantity error indication
- "01011000" when others; -- "X";
-
--- This is state machine m1. It handles receiving the command line, including
--- backspaces, and prints error/response messages. It also parses and
--- executes the commands.
-
--- State register
-fsm_proc : process(sys_clk, sys_rst_n)
-
- procedure exec_prep is
- begin
- if (adr_offset=qty_sr) then
- msg_pointer <= "10101"; -- Address of message
- fsm_state <= SEND_OK;
- else
- watchdog_timer_count <= (others=>'0'); -- Reset the timer.
- fsm_state <= EXECUTE;
- end if;
- end exec_prep;
-
-begin
- if (sys_rst_n='0') then -- asynchronous reset
- rst_o <= '0';
- fsm_state <= IDLE;
- command <= INIT;
- msg_pointer <= (others=>'0');
- cmd_ptr <= (others=>'0');
- adr_offset <= (others=>'0');
- adr_freeze <= '0';
- adr_sr <= (others=>'0');
- dat_sr <= (others=>'0');
- qty_sr <= to_unsigned(1,qty_sr'length); -- Set qty = 1 default.
- display_field_count <= (others=>'0');
- display_adr_digit_count <= (others=>'0');
- display_dat_digit_count <= (others=>'0');
- watchdog_timer_count <= (others=>'0');
- display_adr_sr <= (others=>'0');
- cmd_done_o <= '0';
- comment_area <= '0';
- elsif (sys_clk'event and sys_clk='1') then
- if (sys_clk_en='1') then
-
- -- Handle the Watchdog timer
- if (watchdog_timer_done='0') then
- watchdog_timer_count <= watchdog_timer_count+1;
- end if;
-
- -- Default values for outputs. The individual states can override these.
- rst_o <= '0';
- cmd_done_o <= '0';
-
- case (fsm_state) is
-
- when IDLE =>
- msg_pointer <= (others=>'0');
- fsm_state <= SEND_WELCOME_STRING;
-
- when SEND_WELCOME_STRING =>
- if (resp_cyc_l='1' and resp_ack_i='1') then
- if (msg_pointer=15) then -- Send initial string ("0123456789ABCDEF")
- msg_pointer <= "10111"; -- Address of the message
- fsm_state <= SEND_PROMPT;
- else
- msg_pointer <= msg_pointer+1;
- end if;
- end if;
-
- when SEND_OK =>
- if (resp_cyc_l='1' and resp_ack_i='1') then
- if (msg_pointer=22) then -- Send 2 characters...
- msg_pointer <= "10111"; -- Address of the message
- fsm_state <= SEND_PROMPT;
- else
- msg_pointer <= msg_pointer+1;
- end if;
- end if;
-
- when SEND_PROMPT =>
- if (resp_cyc_l='1' and resp_ack_i='1') then
- if (msg_pointer=27) then -- Send 5 characters...
- cmd_ptr <= (others=>'0');
- cmd_done_o <= '1';
- fsm_state <= CHECK_NEW_CHAR;
- else
- msg_pointer <= msg_pointer+1;
- end if;
- end if;
-
- -- This state always leads to activating the parser...
- when SEND_CRLF =>
- if (resp_cyc_l='1' and resp_ack_i='1') then
- if (msg_pointer=24) then -- Send 2 characters...
- cmd_ptr <= (others=>'0');
- fsm_state <= SCAN_CMD;
- else
- msg_pointer <= msg_pointer+1;
- end if;
- end if;
-
- when CHECK_NEW_CHAR =>
- if (cmd_we_i='1') then
- if (cmd_char_i=BACKSPACE_CHAR) then
- cmd_ptr <= cmd_ptr-1; -- This effectively eliminates the last char
- elsif (comment_area='0' and cmd_char_i=ENTER_CHAR) or (cmd_ptr=CMD_BUFFER_SIZE-1) then
- if (cmd_char_i=ENTER_CHAR) then
- msg_pointer <= "10111"; -- Address of the message
- fsm_state <= SEND_CRLF;
- end if;
- if (cmd_ptr=CMD_BUFFER_SIZE-1) then
- msg_pointer <= "10111"; -- Address of the message.
- cmd_ptr <= (others=>'0');
- fsm_state <= PARSE_ERR_INDICATOR_CRLF;
- end if;
- elsif (cmd_char_i=COMMENT_CHAR) then
- comment_area <= '1'; -- Activate comment area, which stores characters, but does not advance cmd_ptr.
- elsif (comment_area='0') then
- cmd_ptr <= cmd_ptr+1;
- end if;
- -- Deactivate comment area at end of line
- if (comment_area='1' and cmd_char_i=ENTER_CHAR) then
- comment_area <= '0';
- -- Check if a valid command might have preceded the comment
- if (cmd_ptr>1) then
- msg_pointer <= "10111"; -- Address of the message
- fsm_state <= SEND_CRLF;
- else
- msg_pointer <= "10111"; -- Address of the message
- fsm_state <= SEND_PROMPT;
- end if;
- end if;
- end if;
-
- when BG_ERR_INDICATOR =>
- if (resp_cyc_l='1' and resp_ack_i='1') then
- msg_pointer <= "10100"; -- Address of the error message
- fsm_state <= ERR_INDICATOR;
- end if;
-
- -- This state is used when the line is too long...
- when PARSE_ERR_INDICATOR_CRLF =>
- if (resp_cyc_l='1' and resp_ack_i='1') then
- if (msg_pointer=24) then -- Send 2 characters...
- msg_pointer <= "10011"; -- Address of the message.
- fsm_state <= ERR_INDICATOR;
- else
- msg_pointer <= msg_pointer+1;
- end if;
- end if;
-
- when ERR_INDICATOR =>
- if (resp_cyc_l='1' and resp_ack_i='1') then
- msg_pointer <= "10111"; -- Address of the message
- fsm_state <= SEND_PROMPT;
- end if;
-
- when SEND_QUESTION =>
- if (resp_cyc_l='1' and resp_ack_i='1') then
- msg_pointer <= "10011"; -- Address of the message.
- fsm_state <= ERR_INDICATOR;
- end if;
-
- -- The following states are for parsing and executing the command.
-
- -- This state takes care of leading whitespace before the command
- when SCAN_CMD =>
- cmd_ptr <= cmd_ptr+1;
- adr_offset <= (others=>'0');
- case (lc_cmd_char) is
- when "01110010" => -- "r"
- command <= READ;
- fsm_state <= CHECK_SUFFICES;
- when "01110111" => -- "w"
- command <= WRITE;
- qty_sr <= (others=>'1'); -- Limit writes to the max. qty...
- fsm_state <= CHECK_SUFFICES;
- when "01101001" => -- "i"
- command <= INIT;
- qty_sr <= (others=>'0');
- rst_o <= '1'; -- Actually do this one right now!!
- fsm_state <= START_EXECUTION;
- when "01100110" => -- "f"
- command <= FILL;
- fsm_state <= CHECK_SUFFICES;
- when others =>
- if (char_is_whitespace='0') then
- msg_pointer <= "01100"; -- Address of message
- fsm_state <= SEND_QUESTION;
- end if;
- end case;
-
- -- This state cleverly detects command "suffix" modifiers, such
- -- as the '0' modifier, which causes the address to remain frozen.
- -- Invalid or unimplemented suffix modifiers elicit the "C?" response.
- when CHECK_SUFFICES => -- Should that read "check suffixes" Hmmm...
- if (cmd_char="00110000") then -- '0' suffix
- cmd_ptr <= cmd_ptr+1;
- adr_freeze <= '1';
- fsm_state <= SCAN_ADR_WHITESPACE;
- elsif (cmd_char=ENTER_CHAR) then
- fsm_state <= START_EXECUTION; -- Using last values
- elsif (char_is_whitespace='1') then
- adr_freeze <= '0';
- fsm_state <= SCAN_ADR_WHITESPACE;
- else
- msg_pointer <= "01100"; -- Address of message
- fsm_state <= SEND_QUESTION;
- end if;
-
-
- -- The only way to determine the end of a valid field is to find
- -- whitespace. Therefore, char_is_whitespace must be used as an exit
- -- condition from the "get_xxx_field" states. So, this state is used to
- -- scan through any leading whitespace prior to the first field.
- when SCAN_ADR_WHITESPACE =>
- if (char_is_whitespace='1') then
- cmd_ptr <= cmd_ptr+1;
- elsif (cmd_char=ENTER_CHAR) then
- fsm_state <= START_EXECUTION; -- Using last values
- else
- fsm_state <= GET_ADR_FIELD;
- adr_sr <= (others=>'0');
- end if;
-
- when GET_ADR_FIELD =>
- if (char_is_hex='1') then
- adr_sr <= adr_sr(4*(ADR_DIGITS-1)-1 downto 0) & hex_digit;
- cmd_ptr <= cmd_ptr+1;
- elsif (char_is_whitespace='1') then -- Normal exit
- fsm_state <= SCAN_DAT_WHITESPACE;
- elsif (cmd_char=ENTER_CHAR and command=READ) then
- fsm_state <= START_EXECUTION; -- Using last values
- else
- msg_pointer <= "01010"; -- Address of message
- fsm_state <= SEND_QUESTION;
- end if;
-
- when SCAN_DAT_WHITESPACE =>
- -- There is no DAT field for reads, so skip it.
- if (command=READ) then
- fsm_state <= SCAN_QTY_WHITESPACE;
- elsif (char_is_whitespace='1') then
- cmd_ptr <= cmd_ptr+1;
- elsif (cmd_char=ENTER_CHAR) then
- if (command=WRITE) then -- Writing data values done, finish.
- msg_pointer <= "10101"; -- Address of message
- fsm_state <= SEND_OK;
- else
- fsm_state <= START_EXECUTION; -- Using last DATA & QTY values
- end if;
- else
- fsm_state <= GET_DAT_FIELD;
- dat_sr <= (others=>'0');
- end if;
-
- when GET_DAT_FIELD =>
- if (char_is_hex='1') then
- dat_sr <= dat_sr(4*(DAT_DIGITS-1)-1 downto 0) & hex_digit;
- cmd_ptr <= cmd_ptr+1;
- elsif (char_is_whitespace='1') then -- Normal exit
- if (command=WRITE) then
- fsm_state <= START_EXECUTION;
- else
- fsm_state <= SCAN_QTY_WHITESPACE;
- end if;
- elsif (cmd_char=ENTER_CHAR) then
- fsm_state <= START_EXECUTION;
- else
- msg_pointer <= "01101"; -- Address of message
- fsm_state <= SEND_QUESTION;
- end if;
-
- when SCAN_QTY_WHITESPACE =>
- if (char_is_whitespace='1') then
- cmd_ptr <= cmd_ptr+1;
- elsif (cmd_char=ENTER_CHAR) then
- fsm_state <= START_EXECUTION; -- Using last values
- else
- fsm_state <= GET_QTY_FIELD;
- qty_sr <= to_unsigned(0,qty_sr'length);
- end if;
-
- when GET_QTY_FIELD =>
- if (char_is_hex='1') then
- qty_sr <= qty_sr(4*(QTY_DIGITS-1)-1 downto 0) & hex_digit;
- cmd_ptr <= cmd_ptr+1;
- elsif (char_is_whitespace='1' or cmd_char=ENTER_CHAR) then -- Normal exit
- fsm_state <= START_EXECUTION;
- else
- msg_pointer <= "11100"; -- Address of message
- fsm_state <= SEND_QUESTION;
- end if;
-
- -- This state seeks to obtain master_bg_i, which grants the bus for use.
- when START_EXECUTION =>
- watchdog_timer_count <= (others=>'0'); -- Reset the timer.
- display_adr_sr <= adr_ptr;
- display_field_count <= (others=>'0');
- if (master_bg_i='1') then -- skip REQUEST_BUS if it is already granted!
- exec_prep;
- else
- fsm_state <= REQUEST_BUS;
- end if;
-
- when REQUEST_BUS =>
- if (master_bg_i='1') then
- exec_prep; -- resets watchdog, sends "OK" if done.
- elsif (watchdog_timer_done='1') then
- msg_pointer <= "01011"; -- Address of messsage
- fsm_state <= BG_ERR_INDICATOR;
- end if;
-
- -- This single state does fill/write/read depending upon the value
- -- contained in "command"!
- when EXECUTE =>
- if (watchdog_timer_done='1' or err_i='1') then
- fsm_state <= BG_ERR_INDICATOR;
- elsif (ack_i='1') then
- case command is
- when READ =>
- dat_sr <= dat_i; -- Capture the read data
- display_adr_sr <= adr_ptr;
- fsm_state <= DISPLAY_PREP;
- when WRITE =>
- adr_offset <= adr_offset+1;
- fsm_state <= SCAN_DAT_WHITESPACE; -- Continue to next data value
- when FILL =>
- adr_offset <= adr_offset+1;
- fsm_state <= POST_FILL_CYCLE;
- when others =>
- fsm_state <= POST_FILL_CYCLE;
- end case;
- end if;
-
- when POST_FILL_CYCLE =>
- exec_prep; -- resets watchdog, sends "OK" if done.
-
- when DISPLAY_PREP =>
- adr_offset <= adr_offset+1;
- if (display_field_count = 0) then -- Check to see if address display is needed yet.
- msg_pointer <= '0' & display_adr_sr(4*ADR_DIGITS-1 downto 4*(ADR_DIGITS-1));
- display_adr_digit_count <= (others=>'0');
- display_adr_sr <= adr_ptr;
- fsm_state <= DISPLAY_ADR; -- Leads to a new address line.
- else
- display_dat_digit_count <= (others=>'0');
- msg_pointer <= '0' & dat_sr(4*DAT_DIGITS-1 downto 4*(DAT_DIGITS-1));
- fsm_state <= DISPLAY_DAT;
- end if;
-
- when DISPLAY_ADR =>
- if (resp_cyc_l='1' and resp_ack_i='1') then
- if (display_adr_digit_count = ADR_DIGITS-1) then
- msg_pointer <= "10000"; -- Address of the message
- fsm_state <= DISPLAY_SEPARATOR;
- else
- display_adr_sr <= display_adr_sr(4*(ADR_DIGITS-1)-1 downto 0) & to_unsigned(0,4);
- display_adr_digit_count <= display_adr_digit_count+1;
- end if;
- end if;
-
- when DISPLAY_SEPARATOR =>
- if (resp_cyc_l='1' and resp_ack_i='1') then
- msg_pointer <= msg_pointer+1;
- if (msg_pointer = 18) then -- Three characters
- display_dat_digit_count <= (others=>'0');
- msg_pointer <= '0' & dat_sr(4*DAT_DIGITS-1 downto 4*(DAT_DIGITS-1));
- fsm_state <= DISPLAY_DAT;
- end if;
- end if;
-
- when DISPLAY_DAT =>
- if (resp_cyc_l='1' and resp_ack_i='1') then
- if (
- (display_dat_digit_count = DAT_DIGITS-1)
- and (display_field_count = DISPLAY_FIELDS-1)
- )
- then
- msg_pointer <= "10111"; -- Address of the message
- fsm_state <= DISPLAY_CRLF;
- display_field_count <= (others=>'0');
- elsif (display_dat_digit_count = DAT_DIGITS-1) then
- msg_pointer <= "10000"; -- Address of the message
- fsm_state <= DISPLAY_SPACE;
- display_field_count <= display_field_count+1;
- else
- dat_sr <= dat_sr(4*(DAT_DIGITS-1)-1 downto 0) & hex_digit;
- display_dat_digit_count <= display_dat_digit_count+1;
- end if;
- end if;
-
- when DISPLAY_SPACE =>
- if (resp_cyc_l='1' and resp_ack_i='1') then
- exec_prep; -- resets watchdog, sends "OK" if done.
- end if;
-
- when DISPLAY_CRLF =>
- if (resp_cyc_l='1' and resp_ack_i='1') then
- msg_pointer <= msg_pointer+1;
- if (msg_pointer=24) then -- Two characters
- exec_prep; -- resets watchdog, sends "OK" if done.
- end if;
- end if;
-
- --when others =>
- -- fsm_state <= IDLE;
- end case;
-
- end if; -- sys_clk_en
- end if; -- sys_clk
-end process;
-
--- Assert needed outputs during execution of bus cycles
-master_br_o <= '1' when (fsm_state=REQUEST_BUS or fsm_state=EXECUTE) else '0';
-we_l <= '1' when (fsm_state=EXECUTE and (command=WRITE or command=FILL)) else '0';
-stb_l <= '1' when (fsm_state=EXECUTE) else '0';
-
-
--- This is the command buffer writing section
-ram_proc : process(sys_clk,sys_rst_n)
-variable i : natural;
-begin
- if (sys_rst_n='0') then
- -- synthesis translate_off
- -- The initialization of the command buffer is for convenience in simulation only.
- -- It can be removed for synthesis.
- for i in 0 to CMD_BUFFER_SIZE-1 loop
- cmd_buffer(i) <= (others=>'0');
- end loop;
- -- synthesis translate_on
- elsif (sys_clk'event and sys_clk='1') then
- if (sys_clk_en='1') then
- if (cmd_we_i='1' and fsm_state=CHECK_NEW_CHAR) then
- cmd_buffer(to_integer(cmd_ptr)) <= cmd_char_i;
- end if;
- -- Latch the command pointer, for synchronous reads.
- --rd_cmd_ptr <= cmd_ptr; -- Use this to infer BRAM.
- end if;
- end if;
-end process;
-
--- This is the command buffer reading section
-cmd_char <= cmd_buffer(to_integer(cmd_ptr)); -- Asynchronous read. Amazingly, this was the better option in XC2S200E...
---cmd_char <= cmd_buffer(to_integer(rd_cmd_ptr)); -- Synchronous read, use this to infer BRAM.
-lc_cmd_char <= (cmd_char or "00100000"); -- lowercase
-
--- These assigments are for detecting whether the cmd_char is
--- anything of special interest.
-char_is_whitespace <= '1' when ((cmd_char=16#20#) -- space
- or (cmd_char=16#09#) -- tab
- or (cmd_char=16#0A#) -- line feed
- ) else '0';
-char_is_num <= '1' when ((cmd_char>=16#30#) and (cmd_char<=16#39#)) else '0';
-char_is_a_f <= '1' when ((lc_cmd_char>=16#61#) and (lc_cmd_char<=16#66#)) else '0';
-char_is_hex <= char_is_num or char_is_a_f;
-
-hex_digit <= cmd_char(3 downto 0) when char_is_num='1' else (cmd_char(3 downto 0)+"1001");
-
-watchdog_timer_done <= '1' when (watchdog_timer_count=WATCHDOG_VALUE) else '0';
-
-end beh;
-
-
----------------------------------------------------------------------------------------
---
--- Author: John Clayton
--- Date : Nov. 20, 2009
--- Update: 11/20/09 copied this file from rs232_syscon.v Began translating.
--- 10/04/11 Removed msg_offset+msg_base adder, in a bid to
--- increase max operating speed of this module.
--- Combined CMD_ERR_INDICATOR, ADR_ERR_INDICATOR,
--- DAT_ERR_INDICATOR, and QTY_ERR_INDICATOR
--- into a single state : SEND_QUESTION
--- Combined ACK_ERR_INDICATOR and PARSE_ERR_INDICATOR
--- into a single state : ERR_INDICATOR
--- 08/03/13 Removed rs232_tx_active_o, since it appears to be a
--- vestigial relic of a time long ago when the echoing of
--- command characters was done through the UART, and not
--- directly as it is now. It was staying high all the
--- time except for brief pulses low during generated
--- responses... which is not useful.
--- 08/03/13 Added "cmd_done_o" output pulse, which helps outside
--- serial command generators know when to begin generating
--- the next command. Removed the "rs232_" prefix from
--- signal names, since the signals really aren't at RS232
--- levels.
--- 08/03/13 Changed module and packet name to replace "rs232_"
--- with "async_"
--- 08/07/13 Added logic to include a "single line" type of comment
--- which allows initialization strings and messages to
--- include comments, which are echoed back over the
--- interface for the user to perhaps see.
---
--- Description
----------------------------------------------------------------------------------------
--- This module takes an "ascii_syscon" unit and adds an asynchronous serial
--- interface to it.
---
--- For details of command and response syntax, please refer to the ascii_syscon
--- description.
---
----------------------------------------------------------------------------------------
-
-library IEEE;
-use IEEE.STD_LOGIC_1164.ALL;
-use IEEE.NUMERIC_STD.ALL;
-use IEEE.MATH_REAL.ALL;
-
-library work;
-use work.function_pack.all;
-use work.uart_sqclk_pack.all;
-use work.async_syscon_pack.all;
-
-entity async_syscon is
- generic (
- ECHO_COMMANDS : natural := 1; -- set nonzero to echo back command characters
- ADR_DIGITS : natural := 4; -- # of hex digits for address
- DAT_DIGITS : natural := 4; -- # of hex digits for data
- QTY_DIGITS : natural := 2; -- # of hex digits for quantity
- CMD_BUFFER_SIZE : natural := 32; -- # of chars in the command buffer
- WATCHDOG_VALUE : natural := 200; -- # of sys_clks before ack is expected
- DISPLAY_FIELDS : natural := 8 -- # of fields/line
- );
- port (
-
- sys_rst_n : in std_logic;
- sys_clk : in std_logic;
- sys_clk_en : in std_logic;
-
- -- rate and parity
- parity_i : in unsigned(1 downto 0); -- 0=none, 1=even, 2=odd
- baud_clk_i : in std_logic; -- At 1x the desired baud rate, can be squarewave or pulses.
- baud_lock_i : in std_logic; -- '1' Indicates baud clock is stable and ready.
-
- -- Serial IO
- cmd_i : in std_logic;
- resp_o : out std_logic;
- cmd_done_o : out std_logic;
-
- -- Master Bus IO
- master_bg_i : in std_logic;
- master_adr_i : in unsigned(4*ADR_DIGITS-1 downto 0);
- master_dat_i : in unsigned(4*DAT_DIGITS-1 downto 0);
- master_dat_o : out unsigned(4*DAT_DIGITS-1 downto 0);
- master_stb_i : in std_logic;
- master_we_i : in std_logic;
- master_br_o : out std_logic;
-
- -- System Bus IO
- ack_i : in std_logic;
- err_i : in std_logic;
- dat_i : in unsigned(4*DAT_DIGITS-1 downto 0);
- dat_o : out unsigned(4*DAT_DIGITS-1 downto 0);
- rst_o : out std_logic;
- stb_o : out std_logic;
- cyc_o : out std_logic;
- adr_o : out unsigned(4*ADR_DIGITS-1 downto 0);
- we_o : out std_logic
- );
-end async_syscon;
-
-architecture beh of async_syscon is
-
--- Constants
-constant ENTER_CHAR : unsigned := "00001101";
-
--- Signals
- -- For ascii_syscon
-signal cmd_char : unsigned(7 downto 0);
-signal cmd_we_uart : std_logic;
-signal cmd_we_wait : std_logic;
-signal cmd_rx_done : std_logic;
-signal cmd_we : std_logic;
-signal cmd_ack : std_logic;
-signal cmd_echo : std_logic;
-signal resp_char : unsigned(7 downto 0);
-signal resp_cyc : std_logic;
-signal resp_cyc_r1 : std_logic;
-signal resp_cyc_uart : std_logic;
-signal resp_ack_uart : std_logic;
-signal resp_ack_uart_r1 : std_logic;
-signal resp_ack : std_logic;
-
- -- For the serial interface
-signal async_rx_error : unsigned(1 downto 0);
-signal async_rx_restart : std_logic;
-signal resp_l : std_logic;
-
-----------------------------------------------------------------------------
--- Component Declarations
-----------------------------------------------------------------------------
-
-----------------------------------------------------------------------------
-begin
-
-----------------------------------------------------------------------------
--- Instantiations
-----------------------------------------------------------------------------
-
-uart1 : uart_sqclk
- port map (
-
- sys_rst_n => sys_rst_n,
- sys_clk => sys_clk,
- sys_clk_en => sys_clk_en,
-
- -- rate and parity
- parity_i => parity_i,
- rate_clk_i => baud_clk_i,
-
- -- serial I/O
- tx_stream => resp_l,
- rx_stream => cmd_i,
-
- --control and status
- tx_wr_i => resp_cyc_uart,
- tx_dat_i => resp_char,
- tx_done_o => resp_ack_uart,
- rx_restart_i => async_rx_restart, -- High clears error flags, clears rx_done_o
- rx_dat_o => cmd_char,
- rx_wr_o => cmd_we_uart, -- High pulse means store rx_dat_o.
- rx_done_o => cmd_rx_done, -- Remains high after receive, until clk edge with rx_restart_i=1
- frame_err_o => async_rx_error(0), -- High = error. Reset when rx_restart_i asserted.
- parity_err_o => async_rx_error(1) -- High = error. Reset when rx_restart_i asserted.
- );
-
-syscon1 : ascii_syscon
- generic map(
- ADR_DIGITS => ADR_DIGITS, -- # of hex digits for address
- DAT_DIGITS => DAT_DIGITS, -- # of hex digits for data
- QTY_DIGITS => QTY_DIGITS, -- # of hex digits for quantity
- CMD_BUFFER_SIZE => CMD_BUFFER_SIZE, -- # of chars in the command buffer
- WATCHDOG_VALUE => WATCHDOG_VALUE, -- # of sys_clks before ack is expected
- DISPLAY_FIELDS => DISPLAY_FIELDS -- # of fields/line
- )
- port map(
-
- sys_rst_n => sys_rst_n,
- sys_clk => sys_clk,
- sys_clk_en => sys_clk_en,
-
- -- Parallel ASCII I/O
- cmd_char_i => cmd_char,
- cmd_we_i => cmd_we,
- cmd_ack_o => cmd_ack,
- cmd_echo_o => cmd_echo,
- resp_char_o => resp_char,
- resp_cyc_o => resp_cyc,
- resp_ack_i => resp_ack,
- cmd_done_o => cmd_done_o,
-
- -- Master Bus IO
- master_bg_i => master_bg_i,
- master_adr_i => master_adr_i,
- master_dat_i => master_dat_i,
- master_dat_o => master_dat_o,
- master_stb_i => master_stb_i,
- master_we_i => master_we_i,
- master_br_o => master_br_o,
-
- -- System Bus IO
- ack_i => ack_i,
- err_i => err_i,
- dat_i => dat_i,
- dat_o => dat_o,
- rst_o => rst_o,
- stb_o => stb_o,
- cyc_o => cyc_o,
- adr_o => adr_o,
- we_o => we_o
- );
-
-----------------------------------------------------------------------------
--- Module code
-----------------------------------------------------------------------------
-
-async_rx_restart <= async_rx_error(0) or async_rx_error(1) or cmd_ack;
-resp_o <= resp_l when cmd_echo='0' else
- cmd_i when ECHO_COMMANDS/=0 else
- '1';
-
- -- Detect rising edge of resp_ack_uart
- resp_ack_proc: Process(sys_rst_n,sys_clk)
- begin
- if (sys_rst_n = '0') then
- resp_ack_uart_r1 <= '1';
- elsif (sys_clk'event AND sys_clk='1') then
- if (sys_clk_en='1') then
- resp_ack_uart_r1 <= resp_ack_uart;
- end if;
- end if; -- sys_clk
- end process;
- resp_ack <= '1' when resp_ack_uart='1' and resp_ack_uart_r1='0' else '0';
-
- -- Detect rising edge of resp_cyc
- resp_cyc_proc: Process(sys_rst_n,sys_clk)
- begin
- if (sys_rst_n = '0') then
- resp_cyc_r1 <= '1';
- elsif (sys_clk'event AND sys_clk='1') then
- if (sys_clk_en='1') then
- resp_cyc_r1 <= resp_cyc;
- end if;
- end if; -- sys_clk
- end process;
- resp_cyc_uart <= '1' when resp_cyc='1' and resp_cyc_r1='0' else '0';
-
- -- Create a valid command write enable, that waits until the final echoed
- -- character (CHAR_ENTER) is done being transmitted
- cmd_we_proc: Process(sys_rst_n,sys_clk)
- begin
- if (sys_rst_n = '0') then
- cmd_we_wait <= '0';
- elsif (sys_clk'event AND sys_clk='1') then
- if (sys_clk_en='1') then
- if (cmd_we_uart='1' and cmd_we_wait='0') then
- cmd_we_wait <= '1';
- end if;
- if (cmd_we_wait='1') then
- if (cmd_rx_done='1') then
- cmd_we_wait <= '0';
- end if;
- end if;
- end if;
- end if; -- sys_clk
- end process;
-
-cmd_we <= cmd_we_uart when baud_lock_i='1' and cmd_char/=ENTER_CHAR else
- '1' when baud_lock_i='1' and cmd_char=ENTER_CHAR and cmd_we_wait='1' and cmd_rx_done='1' else
- '0';
-
-end beh;
-
-
Index: rs232_syscon/trunk/VHDL/syscon_vhdl_2008_lattice_diamond_project.zip
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: rs232_syscon/trunk/VHDL/syscon_vhdl_2008_lattice_diamond_project.zip
===================================================================
--- rs232_syscon/trunk/VHDL/syscon_vhdl_2008_lattice_diamond_project.zip (revision 8)
+++ rs232_syscon/trunk/VHDL/syscon_vhdl_2008_lattice_diamond_project.zip (nonexistent)
rs232_syscon/trunk/VHDL/syscon_vhdl_2008_lattice_diamond_project.zip
Property changes :
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: rs232_syscon/trunk/VHDL_doc/async_syscon_guide_OC102517.odt
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: rs232_syscon/trunk/VHDL_doc/async_syscon_guide_OC102517.odt
===================================================================
--- rs232_syscon/trunk/VHDL_doc/async_syscon_guide_OC102517.odt (revision 8)
+++ rs232_syscon/trunk/VHDL_doc/async_syscon_guide_OC102517.odt (nonexistent)
rs232_syscon/trunk/VHDL_doc/async_syscon_guide_OC102517.odt
Property changes :
Deleted: svn:mime-type
## -1 +0,0 ##
-application/octet-stream
\ No newline at end of property
Index: rs232_syscon/trunk/VHDL_doc/async_syscon_guide_OC102517.pdf
===================================================================
--- rs232_syscon/trunk/VHDL_doc/async_syscon_guide_OC102517.pdf (revision 8)
+++ rs232_syscon/trunk/VHDL_doc/async_syscon_guide_OC102517.pdf (nonexistent)
@@ -1,1918 +0,0 @@
-%PDF-1.4
-%äüöß
-2 0 obj
-<>
-stream
-xTMk19͌ NBNMcȡ6
-.$=Hu<ͼlCFgB 7XCc`X>U!qy[8罹T(\b/;v;E}lIcД1[)qxr771
-oj;X.%~1g6DLƉ\e;XEъ-TIM!W,E纮Dqi{5(_#4b採I"y
-8+m2QGEo\%[|~MʄSLP2W&Tyt6T؉meGv5R`-KVM">ypR?=U9i
-6ΰ+1Hl_BC+:TNiImՎY)tGEOhpboh1FL03"TcyKA߇s`^VWL=~V4h@?hޓ2OLp͎MB%i#/~M!0:Bw@;@ R;t3yރ#,3(7dt~hjvY"ȫBP%2sGq~
-endstream
-endobj
-
-3 0 obj
-655
-endobj
-
-6 0 obj
-<>
-stream
-x[I6ׯ9ܵ斤!!,0d3y$˖Jo΄w.IO"8S#qԍ4ȣk>~o~;m
-4{j?Bj3+h`l/F~<~}xw<~
-:Rp.BoJNAp[zKG`hLѷӶ + `|+/a`b^`|{)TDp']/ ^p@ӕǶ:lԱu
-{]EȨlW:ᥗ,\OBĎ5&(Wv7n(8sTKh3'Gp0H$D#/djQ|KmF( }&Em"JpLJ!`th}B@K9Uh
-lu /<1W}ݴ)ˡ&/Y)
-|e*J[$LM|q*lY`NʤDM5{k(%,}GԷڐQ{Wn-w(qxV
-Tī;1M%:9Z[ H%8 Z|.E\opua
-y!JEp"ىRzm-8YsO%'kuR__0Z.uU!}Cx,)
-m"˜AJ3ь 7ƯțmD]꺉E~TD FtOP{kh+/yJ_8B̿j4-=JwjFyBŲ:\6hX2wUz]
-::>gt~Mڽxڔze}c8>ck
-I[R9d:`N'(~젔>ںػXxmĝn<+#5udiK*<fT6ywFTఈ8q:W;7f^[#ot[9'Z ͨ9z