OpenCores
URL https://opencores.org/ocsvn/rs232_syscon/rs232_syscon/trunk

Subversion Repositories rs232_syscon

[/] [rs232_syscon/] [trunk/] [VHDL/] [async_syscon_pack.vhd] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 jclaytons
--------------------------------------------------------------------------
2
-- Package of async_syscon components
3
--
4
 
5
library IEEE;
6
use IEEE.STD_LOGIC_1164.ALL;
7
use IEEE.NUMERIC_STD.ALL;
8
 
9
package async_syscon_pack is
10
 
11
  -- A system controller with an 8-bit parallel ASCII interface
12
  component ascii_syscon
13
    generic (
14
      ADR_DIGITS      : natural; -- # of hex digits for address
15
      DAT_DIGITS      : natural; -- # of hex digits for data
16
      QTY_DIGITS      : natural; -- # of hex digits for quantity
17
      CMD_BUFFER_SIZE : natural; -- # of chars in the command buffer
18
      WATCHDOG_VALUE  : natural; -- # of sys_clks before ack is expected
19
      DISPLAY_FIELDS  : natural  -- # of fields/line
20
    );
21
    port (
22
 
23
      sys_rst_n    : in  std_logic;
24
      sys_clk      : in  std_logic;
25
      sys_clk_en   : in  std_logic;
26
 
27
      -- Parallel ASCII I/O
28
      cmd_char_i   : in  unsigned(7 downto 0);
29
      cmd_we_i     : in  std_logic;
30
      cmd_ack_o    : out std_logic;
31
      cmd_echo_o   : out std_logic;
32
      resp_char_o  : out unsigned(7 downto 0);
33
      resp_cyc_o   : out std_logic;
34
      resp_ack_i   : in  std_logic;
35
      cmd_done_o   : out std_logic;
36
 
37
      -- Master Bus IO
38
      master_bg_i  : in  std_logic;
39
      master_adr_i : in  unsigned(4*ADR_DIGITS-1 downto 0);
40
      master_dat_i : in  unsigned(4*DAT_DIGITS-1 downto 0);
41
      master_dat_o : out unsigned(4*DAT_DIGITS-1 downto 0);
42
      master_stb_i : in  std_logic;
43
      master_we_i  : in  std_logic;
44
      master_br_o  : out std_logic;
45
 
46
      -- System Bus IO
47
      ack_i        : in  std_logic;
48
      err_i        : in  std_logic;
49
      dat_i        : in  unsigned(4*DAT_DIGITS-1 downto 0);
50
      dat_o        : out unsigned(4*DAT_DIGITS-1 downto 0);
51
      rst_o        : out std_logic;
52
      stb_o        : out std_logic;
53
      cyc_o        : out std_logic;
54
      adr_o        : out unsigned(4*ADR_DIGITS-1 downto 0);
55
      we_o         : out std_logic
56
    );
57
  end component;
58
 
59
  -- ascii_syscon mounted with a UART interface
60
  component async_syscon
61
    generic (
62
      ECHO_COMMANDS   : natural; -- set nonzero to echo back command characters
63
      ADR_DIGITS      : natural; -- # of hex digits for address
64
      DAT_DIGITS      : natural; -- # of hex digits for data
65
      QTY_DIGITS      : natural; -- # of hex digits for quantity
66
      CMD_BUFFER_SIZE : natural; -- # of chars in the command buffer
67
      WATCHDOG_VALUE  : natural; -- # of sys_clks before ack is expected
68
      DISPLAY_FIELDS  : natural  -- # of fields/line
69
    );
70
    port (
71
 
72
      sys_rst_n    : in  std_logic;
73
      sys_clk      : in  std_logic;
74
      sys_clk_en   : in  std_logic;
75
 
76
      -- rate and parity
77
      parity_i     : in  unsigned(1 downto 0); -- 0=none, 1=even, 2=odd
78
      baud_clk_i   : in  std_logic; -- At 1x the desired baud rate, can be squarewave or pulses.
79
      baud_lock_i  : in  std_logic; -- '1' Indicates baud clock is stable and ready.
80
 
81
      -- Serial IO
82
      cmd_i        : in  std_logic;
83
      resp_o       : out std_logic;
84
      cmd_done_o   : out std_logic;
85
 
86
      -- Master Bus IO
87
      master_bg_i  : in  std_logic;
88
      master_adr_i : in  unsigned(4*ADR_DIGITS-1 downto 0);
89
      master_dat_i : in  unsigned(4*DAT_DIGITS-1 downto 0);
90
      master_dat_o : out unsigned(4*DAT_DIGITS-1 downto 0);
91
      master_stb_i : in  std_logic;
92
      master_we_i  : in  std_logic;
93
      master_br_o  : out std_logic;
94
 
95
      -- System Bus IO
96
      ack_i        : in  std_logic;
97
      err_i        : in  std_logic;
98
      dat_i        : in  unsigned(4*DAT_DIGITS-1 downto 0);
99
      dat_o        : out unsigned(4*DAT_DIGITS-1 downto 0);
100
      rst_o        : out std_logic;
101
      stb_o        : out std_logic;
102
      cyc_o        : out std_logic;
103
      adr_o        : out unsigned(4*ADR_DIGITS-1 downto 0);
104
      we_o         : out std_logic
105
    );
106
  end component;
107
 
108
end async_syscon_pack;
109
 
110
package body async_syscon_pack is
111
end async_syscon_pack;
112
 
113
---------------------------------------------------------------------------------------
114
--
115
-- Author: John Clayton
116
-- Date  : Dec. 27, 2013
117
-- Update: 12/27/13 copied async_syscon module, removed the serial interface.
118
--         02/05/14 Added line feed as a whitespace character, to 
119
--                  char_is_whitespace.
120
--         02/06/14 Made resp_cyc a direct function of the state machine state.
121
--                  This allows it to be asserted even when resp_ack_i is tied
122
--                  to '1' all the time...
123
--         02/13/14 Made a slight enhancement to the processing of comments.
124
--                  Previously, all comments were treated as "full line"
125
--                  comments, causing any valid commands preceding the
126
--                  comment to be ignored, since the entire line was being
127
--                  ignored.  I realized that a very small value
128
--                  check on cmd_ptr could differentiate between full line
129
--                  comments, and ones for which there might actually be
130
--                  a valid command.  The enhanced design can process the
131
--                  valid commands.
132
--         02/14/14 Happy Valentine's Day!  Fixed a "wacky" bug which caused
133
--                  an extra digit to be displayed for address and data fields.
134
--                  Added "0" command suffix, which prevents the bus address
135
--                  from incrementing during read, write and fill operations.
136
--                  It's useful for working with FIFOs that have read/write
137
--                  ports mapped to a single address, instead of a whole
138
--                  range of addresses.
139
--         02/27/14 Refined the CHECK_SUFFICES state by adding a jump to
140
--                  START_EXECUTION when ENTER_CHAR is found in the suffix
141
--                  position, thus preserving the "repeat last read with
142
--                  previous address and quantity" function.
143
--
144
-- Description
145
---------------------------------------------------------------------------------------
146
-- This is an 8-bit parallel ASCII character driven interface to a system
147
-- controller driving a "Wishbone" type of parallel system bus.
148
--
149
-- Specifically, the unit allows the user to send text commands to the 
150
-- "ascii_syscon" unit, in order to generate read and write cycles on the
151
-- Wishbone compatible bus.  The command structure is quite terse and spartan
152
-- in nature, this is for the sake of the logic itself.
153
--
154
-- The command line buffer is small enough to be implemented without the use
155
-- of dedicated BRAM memory blocks, and the menus and command responses were
156
-- kept as small as possible.  In most cases, the responses from the unit to
157
-- the user consist of a "newline" and one or two visible characters.  The
158
-- command structure consists of the following commands and responses:
159
--
160
-- Command Syntax              Purpose
161
-- ---------------             ---------------------------------------
162
-- w aaaa dddd dddd dddd...    Write data items "dddd" starting at address "aaaa"
163
--                             using sequential addresses.
164
--                             (If the data field is missing, nothing is done).
165
-- w0 aaaa dddd dddd dddd...   Write data items "dddd" at address "aaaa"
166
--                             without incrementing the address.
167
--                             (If the data field is missing, nothing is done).
168
-- f aaaa dddd xx              "Fill": Write data "dddd" starting at address "aaaa"
169
--                             perform this "xx" times at sequential addresses.
170
--                             (The quantity field is optional, default is 1).
171
-- f0 aaaa dddd xx             "Fill": Write data "dddd" starting at address "aaaa"
172
--                             perform this "xx" times at the same address.
173
--                             (The quantity field is optional, default is 1).
174
-- r aaaa xx                   Read data starting from address "aaaa."
175
--                             Perform this "xx" times at sequential addresses.
176
--                             (The quantity field is optional, default is 1).
177
-- r0 aaaa xx                  Read data from address "aaaa."
178
--                             Perform this "xx" times, using the same address.
179
--                             (The quantity field is optional, default is 1).
180
-- i                           Send a reset pulse to the system. (initialize).
181
--
182
-- <COMMENT_CHAR>              "Single Line" type Comment token.  Characters
183
--                             after the token are ignored until <ENTER>.
184
--                             This enables applications which send
185
--                             files to the unit to include comments for
186
--                             display and as an aid to understanding.
187
--                             The comment token is a constant, change it
188
--                             to be whatever makes sense!
189
--
190
-- Response from async_syscon  Meaning
191
-- --------------------------  ---------------------------------------
192
-- OK                          Command received and performed.  No errors.
193
-- ?                           Command buffer full, without receiving "enter."
194
-- C?                          Command not recognized.
195
-- A?                          Address field syntax error.
196
-- D?                          Data field syntax error.
197
-- Q?                          Quantity field syntax error.
198
-- !                           No "ack_i", or else "err_i" received from bus.
199
-- B!                          No "bg_i" received from master.
200
--
201
-- NOTES on the operation of this unit:
202
--
203
-- - The unit generates a command prompt which is "-> ".
204
-- - Capitalization is not important.
205
-- - Each command is terminated by the "enter" key (0x0d character).
206
--   Commands are executed as soon as "enter" is received.
207
-- - Trailing parameters need not be re-entered.  Their values will
208
--   remain the same as their previous settings.
209
-- - Use of the backspace key is supported, so mistakes can be corrected.
210
-- - The length of the command line is limited to a fixed number of
211
--   characters, as configured by parameter.
212
-- - Fields are separated by white space, including "tab" and/or "space"
213
-- - All numerical fields are interpreted as hexadecimal numbers.
214
--   Decimal is not supported.
215
-- - Numerical field values are retained between commands.  If a "r" is issued
216
--   without any fields following it, the previous values will be used.  A
217
--   set of "quantity" reads will take place at sequential addresses.
218
--   If a "f" is issued without any fields following it, the previous data
219
--   value will be written "quantity" times at sequential addresses, starting
220
--   from the next location beyond where the last command ended.
221
-- - If the user does not wish to use "ack" functionality, simply tie the
222
--   "ack_i" input to logic 1, and then the ! response will never be generated.
223
-- - The data which is read in by the "r" command is displayed using lines
224
--   which begin with the address, followed by the data fields.  The number
225
--   of data fields displayed per line (following the address) is adjustable
226
--   by setting a parameter.  No other display format adjustments can be made.
227
-- - There is currently only a single watchdog timer.  It begins to count at
228
--   the time the "enter" is received to execute a command.  If the bus is granted
229
--   and the ack is received before the expiration of the timer, then the
230
--   cycle will complete normally.  Therefore, the watchdog timeout value
231
--   needs to include time for the request and granting of the bus, in
232
--   addition to the time needed for the actual bus cycle to complete.
233
--
234
--
235
-- Currently, there is only a single indicator (stb_o) generated during bus
236
-- output cycles which are generated from this unit.
237
-- The user can easily implement decoding logic based upon adr_o and stb_o
238
-- which would serve as multiple "stb_o" type signals for different cores
239
-- which would be sharing the same bus.
240
--
241
-- The data bus supported by this module is separate input/output type of bus.
242
-- However, if a single tri-state dat_io bus is desired, it can be added
243
-- to the module without too much trouble.  Supposedly the only difference
244
-- between the two forms of data bus is that one of them avoids using tri-state
245
-- at the cost of doubling the number of interconnects used to carry data back
246
-- and forth...  Some people say that tri-state should be avoided for use
247
-- in internal busses in ASICs.  Maybe they are right.
248
-- But in FPGAs tri-state seems to work pretty well, even for internal busses.
249
--
250
-- Parameters are provided to configure the width of the different command
251
-- fields.  To simplify the logic for binary to hexadecimal conversion, these
252
-- parameters allow adjustment in units of 1 hex digit, not anything smaller.
253
-- If your bus has 10 bits, for instance, simply set the address width to 3
254
-- which produces 12 bits, and then just don't use the 2 msbs of address
255
-- output.
256
--
257
-- No support for the optional Wishbone "retry" (rty_i) input is provided at
258
-- this time.
259
-- No support for "tagn_o" bits is provided at this time, although a register
260
-- might be added external to this module in order to implement to tag bits.
261
-- No BLOCK or RMW cycles are supported currently, so cyc_o is equivalent to
262
-- stb_o...
263
-- The output busses are not tri-stated.  The user may add tri-state buffers
264
-- external to the module, using "stb_o" to enable the buffer outputs.
265
--
266
---------------------------------------------------------------------------------------
267
 
268
library IEEE;
269
use IEEE.STD_LOGIC_1164.ALL;
270
use IEEE.NUMERIC_STD.ALL;
271
 
272
library work;
273
use work.function_pack.all;
274
use work.async_syscon_pack.all;
275
 
276
entity ascii_syscon is
277
    generic (
278
      ADR_DIGITS      : natural :=   4; -- # of hex digits for address
279
      DAT_DIGITS      : natural :=   4; -- # of hex digits for data
280
      QTY_DIGITS      : natural :=   2; -- # of hex digits for quantity
281
      CMD_BUFFER_SIZE : natural :=  32; -- # of chars in the command buffer
282
      WATCHDOG_VALUE  : natural := 200; -- # of sys_clks before ack is expected
283
      DISPLAY_FIELDS  : natural :=   8  -- # of fields/line
284
    );
285
    port (
286
 
287
      sys_rst_n    : in  std_logic;
288
      sys_clk      : in  std_logic;
289
      sys_clk_en   : in  std_logic;
290
 
291
      -- Parallel ASCII I/O
292
      cmd_char_i   : in  unsigned(7 downto 0);
293
      cmd_we_i     : in  std_logic;
294
      cmd_ack_o    : out std_logic;
295
      cmd_echo_o   : out std_logic;
296
      resp_char_o  : out unsigned(7 downto 0);
297
      resp_cyc_o   : out std_logic;
298
      resp_ack_i   : in  std_logic;
299
      cmd_done_o   : out std_logic;
300
 
301
      -- Master Bus IO
302
      master_bg_i  : in  std_logic;
303
      master_adr_i : in  unsigned(4*ADR_DIGITS-1 downto 0);
304
      master_dat_i : in  unsigned(4*DAT_DIGITS-1 downto 0);
305
      master_dat_o : out unsigned(4*DAT_DIGITS-1 downto 0);
306
      master_stb_i : in  std_logic;
307
      master_we_i  : in  std_logic;
308
      master_br_o  : out std_logic;
309
 
310
      -- System Bus IO
311
      ack_i        : in  std_logic;
312
      err_i        : in  std_logic;
313
      dat_i        : in  unsigned(4*DAT_DIGITS-1 downto 0);
314
      dat_o        : out unsigned(4*DAT_DIGITS-1 downto 0);
315
      rst_o        : out std_logic;
316
      stb_o        : out std_logic;
317
      cyc_o        : out std_logic;
318
      adr_o        : out unsigned(4*ADR_DIGITS-1 downto 0);
319
      we_o         : out std_logic
320
    );
321
end ascii_syscon;
322
 
323
library IEEE;
324
use IEEE.STD_LOGIC_1164.ALL;
325
use IEEE.NUMERIC_STD.ALL;
326
 
327
architecture beh of ascii_syscon is
328
 
329
-- Constants
330
constant CMD_PTR_BITS                 : natural := bit_width(CMD_BUFFER_SIZE);
331
constant DISPLAY_FIELD_COUNT_BITS     : natural := bit_width(DISPLAY_FIELDS);
332
constant DISPLAY_ADR_DIGIT_COUNT_BITS : natural := bit_width(ADR_DIGITS);
333
constant DISPLAY_DAT_DIGIT_COUNT_BITS : natural := bit_width(DAT_DIGITS);
334
constant WATCHDOG_TIMER_BITS          : natural := timer_width(WATCHDOG_VALUE);
335
 
336
constant BACKSPACE_CHAR      : unsigned := "00001000";
337
constant ENTER_CHAR          : unsigned := "00001101";
338
constant COMMENT_CHAR        : unsigned := "00100011"; -- '#' character
339
--constant COMMENT_CHAR        : unsigned := "00101101"; -- '-' character
340
 
341
-- Internal signal declarations
342
  -- For the state machine
343
type FSM_STATE_TYPE is (IDLE, SEND_WELCOME_STRING, SEND_OK, SEND_PROMPT,
344
                        CHECK_NEW_CHAR, SEND_CRLF, PARSE_ERR_INDICATOR_CRLF,
345
                        ERR_INDICATOR, BG_ERR_INDICATOR, SEND_QUESTION,
346
                        SCAN_CMD, CHECK_SUFFICES, SCAN_ADR_WHITESPACE,
347
                        GET_ADR_FIELD, SCAN_DAT_WHITESPACE, GET_DAT_FIELD,
348
                        SCAN_QTY_WHITESPACE, GET_QTY_FIELD, START_EXECUTION,
349
                        REQUEST_BUS, EXECUTE, DISPLAY_PREP, DISPLAY_ADR,
350
                        DISPLAY_SEPARATOR, DISPLAY_DAT, DISPLAY_SPACE,
351
                        DISPLAY_CRLF, POST_FILL_CYCLE);
352
 
353
signal fsm_state      : FSM_STATE_TYPE;
354
 
355
signal watchdog_timer_done  : std_logic;  -- High when watchdog timer is expired
356
signal char_is_whitespace   : std_logic;  -- High when cmd_buffer[char_count] is whitespace.
357
signal char_is_num          : std_logic;  -- High when cmd_buffer[char_count] is 0..9
358
signal char_is_a_f          : std_logic;  -- High when cmd_buffer[char_count] is a..f
359
signal char_is_hex          : std_logic;  -- High when cmd_buffer[char_count] is a hex char.
360
signal msg_pointer          : unsigned(4 downto 0);  -- Determines message position or address.
361
signal msg_select           : unsigned(4 downto 0);  -- selection of msg_pointer or display value
362
signal hex_digit            : unsigned(3 downto 0);  -- This is the digit to be stored.
363
 
364
signal msg_char             : unsigned(7 downto 0);  -- Selected response message character.
365
signal comment_area         : std_logic;
366
 
367
    -- For the buses
368
signal adr_ptr              : unsigned(4*ADR_DIGITS-1 downto 0);  -- = adr_sr + adr_offset
369
 
370
signal stb_l                : std_logic;  -- "local" stb signal (to distinguish from stb_o)
371
signal we_l                 : std_logic;  -- "local" we  signal (to distinguish from we_o)
372
 
373
signal display_adr_sr       : unsigned(4*ADR_DIGITS-1 downto 0); -- sr for printing addresses
374
signal adr_sr               : unsigned(4*ADR_DIGITS-1 downto 0); -- "nibble" shift register
375
signal dat_sr               : unsigned(4*DAT_DIGITS-1 downto 0); -- "nibble" shift register
376
signal qty_sr               : unsigned(4*QTY_DIGITS-1 downto 0); -- "nibble" shift register
377
 
378
-- The command register has these values
379
type CMD_REG_TYPE is (INIT, READ, FILL, WRITE);
380
signal command : CMD_REG_TYPE;
381
 
382
    -- For the command buffer
383
signal cmd_ptr              : unsigned(CMD_PTR_BITS-1 downto 0); -- Offset from start of command.
384
--signal rd_cmd_ptr           : unsigned(CMD_PTR_BITS-1 downto 0); -- Latched cmd_ptr, use to infer BRAM.
385
type cmd_array_type is
386
  array (integer range 0 to CMD_BUFFER_SIZE-1) of unsigned(7 downto 0);
387
 
388
signal cmd_buffer  : cmd_array_type;
389
signal cmd_char    : unsigned(7 downto 0);
390
signal lc_cmd_char : unsigned(7 downto 0); -- Lowercase version of cmd_char
391
signal adr_offset  : unsigned(4*QTY_DIGITS-1 downto 0);   -- counts from 0 to qty_sr
392
signal adr_freeze  : std_logic; -- When set, prevents adr_offset from incrementing
393
 
394
signal resp_cyc                : std_logic; -- high for response type states
395
signal resp_cyc_l              : std_logic;
396
signal resp_cyc_mask           : std_logic; -- Used to lower resp_cyc_o for one clock cycle, upon acknowledgement.
397
 
398
    -- For various counters
399
signal display_field_count     : unsigned(DISPLAY_FIELD_COUNT_BITS-1 downto 0);      -- "fields displayed"
400
signal display_adr_digit_count : unsigned(DISPLAY_ADR_DIGIT_COUNT_BITS-1 downto 0);  -- "digits displayed"
401
signal display_dat_digit_count : unsigned(DISPLAY_DAT_DIGIT_COUNT_BITS-1 downto 0);  -- "digits displayed"
402
signal watchdog_timer_count    : unsigned(WATCHDOG_TIMER_BITS-1 downto 0);
403
 
404
----------------------------------------------------------------------------
405
-- Component Declarations
406
----------------------------------------------------------------------------
407
 
408
----------------------------------------------------------------------------
409
begin
410
 
411
-- In this module, command characters are accepted immediately but only when in the CHECK_NEW_CHAR state.
412
cmd_ack_o <= '1' when cmd_we_i='1' and fsm_state=CHECK_NEW_CHAR else '0';
413
 
414
-- Provide response character cycle active signal
415
resp_cyc   <= '1' when fsm_state=DISPLAY_CRLF             or
416
                       fsm_state=DISPLAY_SPACE            or
417
                       fsm_state=DISPLAY_DAT              or
418
                       fsm_state=DISPLAY_SEPARATOR        or
419
                       fsm_state=DISPLAY_ADR              or
420
                       fsm_state=SEND_QUESTION            or
421
                       fsm_state=ERR_INDICATOR            or
422
                       fsm_state=PARSE_ERR_INDICATOR_CRLF or
423
                       fsm_state=BG_ERR_INDICATOR         or
424
                       fsm_state=SEND_CRLF                or
425
                       fsm_state=SEND_PROMPT              or
426
                       fsm_state=SEND_OK                  or
427
                       fsm_state=SEND_WELCOME_STRING      else
428
                       '0';
429
-- Implement the "courtesy" of lowering resp_cyc_o for one cycle after resp_ack_i is recognized.
430
-- This increases the amount of time needed for data transfer, and some would say it is needless,
431
-- since a "burst" type transfer also can work.  Since burst transfers were not intended here,
432
-- this is being done anyway.  You see, burst transfers can "tie up" bus arbiters for the entire
433
-- burst, which is not desirable in this design.
434
resp_cyc_l <= '1' when resp_cyc='1' and resp_cyc_mask='0' else '0';
435
resp_cyc_o <= resp_cyc_l;
436
 
437
resp_cyc_mask_proc : process(sys_clk,sys_rst_n)
438
variable i : natural;
439
begin
440
  if (sys_rst_n='0') then
441
    resp_cyc_mask <= '0';
442
  elsif (sys_clk'event and sys_clk='1') then
443
    if (sys_clk_en='1') then
444
      resp_cyc_mask <= '0'; -- Default value
445
      if (resp_cyc_l='1' and resp_ack_i='1') then
446
        resp_cyc_mask <= '1';
447
      end if;
448
    end if;
449
  end if;
450
end process;
451
 
452
 
453
-- Provide command echo indication, to allow ASCII response data to be
454
-- echoed or not, as desired.
455
cmd_echo_o <= '1' when fsm_state=CHECK_NEW_CHAR else '0';
456
 
457
-- Provide parallel ASCII response data
458
resp_char_o <= msg_char;
459
 
460
-- Select which bus signals get used on the system bus
461
adr_o <= adr_ptr when (master_bg_i='1') else master_adr_i;
462
we_o  <= we_l    when (master_bg_i='1') else master_we_i;
463
stb_o <= stb_l   when (master_bg_i='1') else master_stb_i;
464
cyc_o <= stb_l   when (master_bg_i='1') else master_stb_i; -- Separate cyc_o is not yet supported!
465
 
466
dat_o <= dat_sr when (master_bg_i='1' and we_l='1' and stb_l='1') else master_dat_i;
467
master_dat_o <= dat_i;
468
 
469
-- This forms the adress pointer which is used on the bus.
470
adr_ptr <= adr_sr + adr_offset when adr_freeze='0' else adr_sr;
471
 
472
-- This is the ROM for the ASCII characters to be transmitted.
473
-- Choose which value to use
474
msg_select <= '0' & display_adr_sr(4*ADR_DIGITS-1 downto 4*(ADR_DIGITS-1)) when fsm_state=DISPLAY_ADR else
475
              '0' & dat_sr(4*DAT_DIGITS-1 downto 4*(DAT_DIGITS-1))         when fsm_state=DISPLAY_DAT else
476
              msg_pointer;
477
with (msg_select) select
478
  msg_char <=
479
    "00110000" when "00000",  --  "0"; -- Hexadecimal characters
480
    "00110001" when "00001",  --  "1";
481
    "00110010" when "00010",  --  "2";
482
    "00110011" when "00011",  --  "3";
483
    "00110100" when "00100",  --  "4";
484
    "00110101" when "00101",  --  "5";
485
    "00110110" when "00110",  --  "6";
486
    "00110111" when "00111",  --  "7";
487
    "00111000" when "01000",  --  "8";
488
    "00111001" when "01001",  --  "9";
489
    "01000001" when "01010",  --  "A"; -- Address error indication
490
    "01000010" when "01011",  --  "B";
491
    "01000011" when "01100",  --  "C"; -- Command error indication
492
    "01000100" when "01101",  --  "D"; -- Data error indication
493
    "01000101" when "01110",  --  "E";
494
    "01000110" when "01111",  --  "F";
495
    "00100000" when "10000",  --  " "; -- Space
496
    "00111010" when "10001",  --  ":"; -- Colon
497
    "00100000" when "10010",  --  " "; -- Space
498
    "00111111" when "10011",  --  "?"; -- Parse error indication
499
    "00100001" when "10100",  --  "!"; -- ack_i/err_i error indication
500
    "01001111" when "10101",  --  "O"; -- "All is well" message
501
    "01001011" when "10110",  --  "K";
502
    "00001101" when "10111",  -- Carriage Return
503
    "00001010" when "11000",  -- Line Feed
504
    "00101101" when "11001",  --  "-"; -- Command Prompt
505
    "00111110" when "11010",  --  ">";
506
    "00100000" when "11011",  --  " ";
507
    "01010001" when "11100",  --  "Q"; -- Quantity error indication
508
    "01011000" when others;   --  "X";
509
 
510
-- This is state machine m1.  It handles receiving the command line, including
511
-- backspaces, and prints error/response messages.  It also parses and
512
-- executes the commands.
513
 
514
-- State register
515
fsm_proc : process(sys_clk, sys_rst_n)
516
 
517
  procedure exec_prep is
518
  begin
519
    if (adr_offset=qty_sr) then
520
      msg_pointer <= "10101"; -- Address of message
521
      fsm_state   <= SEND_OK;
522
    else
523
      watchdog_timer_count <= (others=>'0'); -- Reset the timer.
524
      fsm_state <= EXECUTE;
525
    end if;
526
  end exec_prep;
527
 
528
begin
529
  if (sys_rst_n='0') then -- asynchronous reset
530
    rst_o       <= '0';
531
    fsm_state   <= IDLE;
532
    command     <= INIT;
533
    msg_pointer <= (others=>'0');
534
    cmd_ptr     <= (others=>'0');
535
    adr_offset  <= (others=>'0');
536
    adr_freeze  <= '0';
537
    adr_sr      <= (others=>'0');
538
    dat_sr      <= (others=>'0');
539
    qty_sr     <= to_unsigned(1,qty_sr'length); -- Set qty = 1 default.
540
    display_field_count      <= (others=>'0');
541
    display_adr_digit_count  <= (others=>'0');
542
    display_dat_digit_count  <= (others=>'0');
543
    watchdog_timer_count     <= (others=>'0');
544
    display_adr_sr           <= (others=>'0');
545
    cmd_done_o  <= '0';
546
    comment_area <= '0';
547
  elsif (sys_clk'event and sys_clk='1') then
548
    if (sys_clk_en='1') then
549
 
550
      -- Handle the Watchdog timer
551
      if (watchdog_timer_done='0') then
552
        watchdog_timer_count <= watchdog_timer_count+1;
553
      end if;
554
 
555
      -- Default values for outputs.  The individual states can override these.
556
      rst_o <= '0';
557
      cmd_done_o <= '0';
558
 
559
      case (fsm_state) is
560
 
561
        when IDLE =>
562
          msg_pointer <= (others=>'0');
563
          fsm_state   <= SEND_WELCOME_STRING;
564
 
565
        when SEND_WELCOME_STRING =>
566
          if (resp_cyc_l='1' and resp_ack_i='1') then
567
            if (msg_pointer=15) then  -- Send initial string ("0123456789ABCDEF")
568
              msg_pointer <= "10111"; -- Address of the message
569
              fsm_state   <= SEND_PROMPT;
570
            else
571
              msg_pointer <= msg_pointer+1;
572
            end if;
573
          end if;
574
 
575
        when SEND_OK =>
576
          if (resp_cyc_l='1' and resp_ack_i='1') then
577
            if (msg_pointer=22) then -- Send 2 characters...
578
              msg_pointer <= "10111"; -- Address of the message
579
              fsm_state   <= SEND_PROMPT;
580
            else
581
              msg_pointer <= msg_pointer+1;
582
            end if;
583
          end if;
584
 
585
        when SEND_PROMPT =>
586
          if (resp_cyc_l='1' and resp_ack_i='1') then
587
            if (msg_pointer=27) then -- Send 5 characters...
588
              cmd_ptr     <= (others=>'0');
589
              cmd_done_o  <= '1';
590
              fsm_state   <= CHECK_NEW_CHAR;
591
            else
592
              msg_pointer <= msg_pointer+1;
593
            end if;
594
          end if;
595
 
596
        -- This state always leads to activating the parser...
597
        when SEND_CRLF =>
598
          if (resp_cyc_l='1' and resp_ack_i='1') then
599
            if (msg_pointer=24) then -- Send 2 characters...
600
              cmd_ptr     <= (others=>'0');
601
              fsm_state   <= SCAN_CMD;
602
            else
603
              msg_pointer <= msg_pointer+1;
604
            end if;
605
          end if;
606
 
607
        when CHECK_NEW_CHAR =>
608
          if (cmd_we_i='1') then
609
            if (cmd_char_i=BACKSPACE_CHAR) then
610
              cmd_ptr <= cmd_ptr-1; -- This effectively eliminates the last char
611
            elsif (comment_area='0' and cmd_char_i=ENTER_CHAR) or (cmd_ptr=CMD_BUFFER_SIZE-1) then
612
              if (cmd_char_i=ENTER_CHAR) then
613
                msg_pointer <= "10111";     -- Address of the message
614
                fsm_state   <= SEND_CRLF;
615
              end if;
616
              if (cmd_ptr=CMD_BUFFER_SIZE-1) then
617
                msg_pointer <= "10111";    -- Address of the message.
618
                cmd_ptr     <= (others=>'0');
619
                fsm_state   <= PARSE_ERR_INDICATOR_CRLF;
620
              end if;
621
            elsif (cmd_char_i=COMMENT_CHAR) then
622
              comment_area <= '1'; -- Activate comment area, which stores characters, but does not advance cmd_ptr.
623
            elsif (comment_area='0') then
624
              cmd_ptr <= cmd_ptr+1;
625
            end if;
626
            -- Deactivate comment area at end of line
627
            if (comment_area='1' and cmd_char_i=ENTER_CHAR) then
628
              comment_area <= '0';
629
              -- Check if a valid command might have preceded the comment
630
              if (cmd_ptr>1) then
631
                msg_pointer <= "10111";     -- Address of the message
632
                fsm_state   <= SEND_CRLF;
633
              else
634
                msg_pointer <= "10111"; -- Address of the message
635
                fsm_state   <= SEND_PROMPT;
636
              end if;
637
            end if;
638
          end if;
639
 
640
        when BG_ERR_INDICATOR =>
641
          if (resp_cyc_l='1' and resp_ack_i='1') then
642
            msg_pointer <= "10100";    -- Address of the error message
643
            fsm_state   <= ERR_INDICATOR;
644
          end if;
645
 
646
        -- This state is used when the line is too long...
647
        when PARSE_ERR_INDICATOR_CRLF =>
648
          if (resp_cyc_l='1' and resp_ack_i='1') then
649
            if (msg_pointer=24) then -- Send 2 characters...
650
              msg_pointer <= "10011";    -- Address of the message.
651
              fsm_state   <= ERR_INDICATOR;
652
            else
653
              msg_pointer <= msg_pointer+1;
654
            end if;
655
          end if;
656
 
657
        when ERR_INDICATOR =>
658
          if (resp_cyc_l='1' and resp_ack_i='1') then
659
            msg_pointer <= "10111"; -- Address of the message
660
            fsm_state   <= SEND_PROMPT;
661
          end if;
662
 
663
        when SEND_QUESTION =>
664
          if (resp_cyc_l='1' and resp_ack_i='1') then
665
            msg_pointer <= "10011";    -- Address of the message.
666
            fsm_state   <= ERR_INDICATOR;
667
          end if;
668
 
669
        -- The following states are for parsing and executing the command.
670
 
671
        -- This state takes care of leading whitespace before the command
672
        when SCAN_CMD =>
673
          cmd_ptr    <= cmd_ptr+1;
674
          adr_offset <= (others=>'0');
675
          case (lc_cmd_char) is
676
            when "01110010" => -- "r"
677
              command   <= READ;
678
              fsm_state <= CHECK_SUFFICES;
679
            when "01110111" => -- "w"
680
              command   <= WRITE;
681
              qty_sr    <= (others=>'1'); -- Limit writes to the max. qty...
682
              fsm_state <= CHECK_SUFFICES;
683
            when "01101001" => -- "i"
684
              command   <= INIT;
685
              qty_sr    <= (others=>'0');
686
              rst_o     <= '1'; -- Actually do this one right now!!
687
              fsm_state <= START_EXECUTION;
688
            when "01100110" => -- "f"
689
              command   <= FILL;
690
              fsm_state <= CHECK_SUFFICES;
691
            when others     =>
692
              if (char_is_whitespace='0') then
693
                msg_pointer <= "01100";    -- Address of message
694
                fsm_state   <= SEND_QUESTION;
695
              end if;
696
          end case;
697
 
698
        -- This state cleverly detects command "suffix" modifiers, such
699
        -- as the '0' modifier, which causes the address to remain frozen.
700
        -- Invalid or unimplemented suffix modifiers elicit the "C?" response.
701
        when CHECK_SUFFICES => -- Should that read "check suffixes" Hmmm...
702
          if (cmd_char="00110000") then -- '0' suffix
703
            cmd_ptr <= cmd_ptr+1;
704
            adr_freeze <= '1';
705
            fsm_state <= SCAN_ADR_WHITESPACE;
706
          elsif (cmd_char=ENTER_CHAR) then
707
            fsm_state <= START_EXECUTION; -- Using last values
708
          elsif (char_is_whitespace='1') then
709
            adr_freeze <= '0';
710
            fsm_state <= SCAN_ADR_WHITESPACE;
711
          else
712
            msg_pointer <= "01100";    -- Address of message
713
            fsm_state   <= SEND_QUESTION;
714
          end if;
715
 
716
 
717
        -- The only way to determine the end of a valid field is to find
718
        -- whitespace.  Therefore, char_is_whitespace must be used as an exit
719
        -- condition from the "get_xxx_field" states.  So, this state is used to
720
        -- scan through any leading whitespace prior to the first field.
721
        when SCAN_ADR_WHITESPACE =>
722
          if (char_is_whitespace='1') then
723
            cmd_ptr <= cmd_ptr+1;
724
          elsif (cmd_char=ENTER_CHAR) then
725
            fsm_state <= START_EXECUTION; -- Using last values
726
          else
727
            fsm_state <= GET_ADR_FIELD;
728
            adr_sr    <= (others=>'0');
729
          end if;
730
 
731
        when GET_ADR_FIELD =>
732
          if (char_is_hex='1') then
733
            adr_sr    <= adr_sr(4*(ADR_DIGITS-1)-1 downto 0) & hex_digit;
734
            cmd_ptr   <= cmd_ptr+1;
735
          elsif (char_is_whitespace='1') then -- Normal exit
736
            fsm_state <= SCAN_DAT_WHITESPACE;
737
          elsif (cmd_char=ENTER_CHAR and command=READ) then
738
            fsm_state <= START_EXECUTION; -- Using last values
739
          else
740
            msg_pointer <= "01010";    -- Address of message
741
            fsm_state   <= SEND_QUESTION;
742
          end if;
743
 
744
        when SCAN_DAT_WHITESPACE =>
745
          -- There is no DAT field for reads, so skip it.
746
          if (command=READ) then
747
            fsm_state <= SCAN_QTY_WHITESPACE;
748
          elsif (char_is_whitespace='1') then
749
            cmd_ptr <= cmd_ptr+1;
750
          elsif (cmd_char=ENTER_CHAR) then
751
            if (command=WRITE) then -- Writing data values done, finish.
752
              msg_pointer <= "10101";    -- Address of message
753
              fsm_state   <= SEND_OK;
754
            else
755
              fsm_state <= START_EXECUTION; -- Using last DATA & QTY values
756
            end if;
757
          else
758
            fsm_state <= GET_DAT_FIELD;
759
            dat_sr    <= (others=>'0');
760
          end if;
761
 
762
        when GET_DAT_FIELD =>
763
          if (char_is_hex='1') then
764
            dat_sr    <= dat_sr(4*(DAT_DIGITS-1)-1 downto 0) & hex_digit;
765
            cmd_ptr   <= cmd_ptr+1;
766
          elsif (char_is_whitespace='1') then -- Normal exit
767
            if (command=WRITE) then
768
              fsm_state  <= START_EXECUTION;
769
            else
770
              fsm_state <= SCAN_QTY_WHITESPACE;
771
            end if;
772
          elsif (cmd_char=ENTER_CHAR) then
773
            fsm_state <= START_EXECUTION;
774
          else
775
            msg_pointer <= "01101";    -- Address of message
776
            fsm_state   <= SEND_QUESTION;
777
          end if;
778
 
779
        when SCAN_QTY_WHITESPACE =>
780
          if (char_is_whitespace='1') then
781
            cmd_ptr   <= cmd_ptr+1;
782
          elsif (cmd_char=ENTER_CHAR) then
783
            fsm_state <= START_EXECUTION; -- Using last values
784
          else
785
            fsm_state <= GET_QTY_FIELD;
786
            qty_sr    <= to_unsigned(0,qty_sr'length);
787
          end if;
788
 
789
        when GET_QTY_FIELD =>
790
          if (char_is_hex='1') then
791
            qty_sr    <= qty_sr(4*(QTY_DIGITS-1)-1 downto 0) & hex_digit;
792
            cmd_ptr   <= cmd_ptr+1;
793
          elsif (char_is_whitespace='1' or cmd_char=ENTER_CHAR) then  -- Normal exit
794
            fsm_state <= START_EXECUTION;
795
          else
796
            msg_pointer <= "11100";    -- Address of message
797
            fsm_state   <= SEND_QUESTION;
798
          end if;
799
 
800
        -- This state seeks to obtain master_bg_i, which grants the bus for use.
801
        when START_EXECUTION =>
802
          watchdog_timer_count <= (others=>'0'); -- Reset the timer.
803
          display_adr_sr       <= adr_ptr;
804
          display_field_count  <= (others=>'0');
805
          if (master_bg_i='1') then -- skip REQUEST_BUS if it is already granted!
806
            exec_prep;
807
          else
808
            fsm_state   <= REQUEST_BUS;
809
          end if;
810
 
811
        when REQUEST_BUS =>
812
          if (master_bg_i='1') then
813
            exec_prep; -- resets watchdog, sends "OK" if done.
814
          elsif (watchdog_timer_done='1') then
815
            msg_pointer <= "01011";    -- Address of messsage
816
            fsm_state   <= BG_ERR_INDICATOR;
817
          end if;
818
 
819
        -- This single state does fill/write/read depending upon the value
820
        -- contained in "command"!
821
        when EXECUTE =>
822
          if (watchdog_timer_done='1' or err_i='1') then
823
            fsm_state   <= BG_ERR_INDICATOR;
824
          elsif (ack_i='1') then
825
            case command is
826
              when READ =>
827
                dat_sr <= dat_i; -- Capture the read data
828
                display_adr_sr <= adr_ptr;
829
                fsm_state <= DISPLAY_PREP;
830
              when WRITE =>
831
                adr_offset <= adr_offset+1;
832
                fsm_state  <= SCAN_DAT_WHITESPACE; -- Continue to next data value
833
              when FILL  =>
834
                adr_offset <= adr_offset+1;
835
                fsm_state  <= POST_FILL_CYCLE;
836
              when others =>
837
                fsm_state  <= POST_FILL_CYCLE;
838
            end case;
839
          end if;
840
 
841
        when POST_FILL_CYCLE =>
842
          exec_prep; -- resets watchdog, sends "OK" if done.
843
 
844
        when DISPLAY_PREP =>
845
          adr_offset <= adr_offset+1;
846
          if (display_field_count = 0) then -- Check to see if address display is needed yet.
847
            msg_pointer <= '0' & display_adr_sr(4*ADR_DIGITS-1 downto 4*(ADR_DIGITS-1));
848
            display_adr_digit_count <= (others=>'0');
849
            display_adr_sr <= adr_ptr;
850
            fsm_state <= DISPLAY_ADR; -- Leads to a new address line.
851
          else
852
            display_dat_digit_count <= (others=>'0');
853
            msg_pointer <= '0' & dat_sr(4*DAT_DIGITS-1 downto 4*(DAT_DIGITS-1));
854
            fsm_state <= DISPLAY_DAT;
855
          end if;
856
 
857
        when DISPLAY_ADR =>
858
          if (resp_cyc_l='1' and resp_ack_i='1') then
859
            if (display_adr_digit_count = ADR_DIGITS-1) then
860
              msg_pointer <= "10000";    -- Address of the message
861
              fsm_state   <= DISPLAY_SEPARATOR;
862
            else
863
              display_adr_sr <= display_adr_sr(4*(ADR_DIGITS-1)-1 downto 0) & to_unsigned(0,4);
864
              display_adr_digit_count <= display_adr_digit_count+1;
865
            end if;
866
          end if;
867
 
868
        when DISPLAY_SEPARATOR =>
869
          if (resp_cyc_l='1' and resp_ack_i='1') then
870
            msg_pointer <= msg_pointer+1;
871
            if (msg_pointer = 18) then -- Three characters
872
              display_dat_digit_count <= (others=>'0');
873
              msg_pointer <= '0' & dat_sr(4*DAT_DIGITS-1 downto 4*(DAT_DIGITS-1));
874
              fsm_state <= DISPLAY_DAT;
875
            end if;
876
          end if;
877
 
878
        when DISPLAY_DAT =>
879
          if (resp_cyc_l='1' and resp_ack_i='1') then
880
            if (
881
                (display_dat_digit_count = DAT_DIGITS-1)
882
                and (display_field_count = DISPLAY_FIELDS-1)
883
                )
884
            then
885
              msg_pointer <= "10111";     -- Address of the message
886
              fsm_state   <= DISPLAY_CRLF;
887
              display_field_count <= (others=>'0');
888
            elsif (display_dat_digit_count = DAT_DIGITS-1) then
889
              msg_pointer <= "10000";    -- Address of the message
890
              fsm_state   <= DISPLAY_SPACE;
891
              display_field_count <= display_field_count+1;
892
            else
893
              dat_sr      <= dat_sr(4*(DAT_DIGITS-1)-1 downto 0) & hex_digit;
894
              display_dat_digit_count <= display_dat_digit_count+1;
895
            end if;
896
          end if;
897
 
898
        when DISPLAY_SPACE =>
899
          if (resp_cyc_l='1' and resp_ack_i='1') then
900
            exec_prep; -- resets watchdog, sends "OK" if done.
901
          end if;
902
 
903
        when DISPLAY_CRLF =>
904
          if (resp_cyc_l='1' and resp_ack_i='1') then
905
            msg_pointer <= msg_pointer+1;
906
            if (msg_pointer=24) then -- Two characters
907
              exec_prep; -- resets watchdog, sends "OK" if done.
908
            end if;
909
          end if;
910
 
911
        --when others => 
912
        --  fsm_state <= IDLE;
913
      end case;
914
 
915
    end if; -- sys_clk_en
916
  end if; -- sys_clk
917
end process;
918
 
919
-- Assert needed outputs during execution of bus cycles
920
master_br_o <= '1' when (fsm_state=REQUEST_BUS or fsm_state=EXECUTE) else '0';
921
we_l        <= '1' when (fsm_state=EXECUTE and (command=WRITE or command=FILL)) else '0';
922
stb_l       <= '1' when (fsm_state=EXECUTE) else '0';
923
 
924
 
925
-- This is the command buffer writing section
926
ram_proc : process(sys_clk,sys_rst_n)
927
variable i : natural;
928
begin
929
  if (sys_rst_n='0') then
930
    -- synthesis translate_off
931
    -- The initialization of the command buffer is for convenience in simulation only.
932
    -- It can be removed for synthesis.
933
     for i in 0 to CMD_BUFFER_SIZE-1 loop
934
       cmd_buffer(i) <= (others=>'0');
935
     end loop;
936
    -- synthesis translate_on
937
  elsif (sys_clk'event and sys_clk='1') then
938
    if (sys_clk_en='1') then
939
      if (cmd_we_i='1' and fsm_state=CHECK_NEW_CHAR) then
940
        cmd_buffer(to_integer(cmd_ptr)) <= cmd_char_i;
941
      end if;
942
      -- Latch the command pointer, for synchronous reads.
943
      --rd_cmd_ptr <= cmd_ptr; -- Use this to infer BRAM.
944
    end if;
945
  end if;
946
end process;
947
 
948
-- This is the command buffer reading section
949
cmd_char <= cmd_buffer(to_integer(cmd_ptr)); -- Asynchronous read.  Amazingly, this was the better option in XC2S200E...
950
--cmd_char <= cmd_buffer(to_integer(rd_cmd_ptr)); -- Synchronous read, use this to infer BRAM.
951
lc_cmd_char <= (cmd_char or "00100000"); -- lowercase
952
 
953
-- These assigments are for detecting whether the cmd_char is
954
-- anything of special interest.
955
char_is_whitespace <= '1' when ((cmd_char=16#20#)  -- space
956
                             or (cmd_char=16#09#)  -- tab
957
                             or (cmd_char=16#0A#)  -- line feed
958
                       ) else '0';
959
char_is_num <= '1' when ((cmd_char>=16#30#) and (cmd_char<=16#39#)) else '0';
960
char_is_a_f <= '1' when ((lc_cmd_char>=16#61#) and (lc_cmd_char<=16#66#)) else '0';
961
char_is_hex <= char_is_num or char_is_a_f;
962
 
963
hex_digit <= cmd_char(3 downto 0) when char_is_num='1' else (cmd_char(3 downto 0)+"1001");
964
 
965
watchdog_timer_done <= '1' when (watchdog_timer_count=WATCHDOG_VALUE) else '0';
966
 
967
end beh;
968
 
969
 
970
---------------------------------------------------------------------------------------
971
--
972
-- Author: John Clayton
973
-- Date  : Nov. 20, 2009
974
-- Update: 11/20/09 copied this file from rs232_syscon.v  Began translating.
975
--         10/04/11 Removed msg_offset+msg_base adder, in a bid to
976
--                  increase max operating speed of this module.
977
--                  Combined CMD_ERR_INDICATOR, ADR_ERR_INDICATOR,
978
--                           DAT_ERR_INDICATOR, and QTY_ERR_INDICATOR
979
--                  into a single state : SEND_QUESTION
980
--                  Combined ACK_ERR_INDICATOR and PARSE_ERR_INDICATOR
981
--                  into a single state : ERR_INDICATOR
982
--         08/03/13 Removed rs232_tx_active_o, since it appears to be a
983
--                  vestigial relic of a time long ago when the echoing of
984
--                  command characters was done through the UART, and not
985
--                  directly as it is now.  It was staying high all the
986
--                  time except for brief pulses low during generated
987
--                  responses... which is not useful.
988
--         08/03/13 Added "cmd_done_o" output pulse, which helps outside
989
--                  serial command generators know when to begin generating
990
--                  the next command.  Removed the "rs232_" prefix from
991
--                  signal names, since the signals really aren't at RS232
992
--                  levels.
993
--         08/03/13 Changed module and packet name to replace "rs232_"
994
--                  with "async_"
995
--         08/07/13 Added logic to include a "single line" type of comment
996
--                  which allows initialization strings and messages to
997
--                  include comments, which are echoed back over the
998
--                  interface for the user to perhaps see.
999
--
1000
-- Description
1001
---------------------------------------------------------------------------------------
1002
-- This module takes an "ascii_syscon" unit and adds an asynchronous serial
1003
-- interface to it.
1004
--
1005
-- For details of command and response syntax, please refer to the ascii_syscon
1006
-- description.
1007
--
1008
---------------------------------------------------------------------------------------
1009
 
1010
library IEEE;
1011
use IEEE.STD_LOGIC_1164.ALL;
1012
use IEEE.NUMERIC_STD.ALL;
1013
use IEEE.MATH_REAL.ALL;
1014
 
1015
library work;
1016
use work.function_pack.all;
1017
use work.uart_sqclk_pack.all;
1018
use work.async_syscon_pack.all;
1019
 
1020
entity async_syscon is
1021
    generic (
1022
      ECHO_COMMANDS   : natural :=         1; -- set nonzero to echo back command characters
1023
      ADR_DIGITS      : natural :=         4; -- # of hex digits for address
1024
      DAT_DIGITS      : natural :=         4; -- # of hex digits for data
1025
      QTY_DIGITS      : natural :=         2; -- # of hex digits for quantity
1026
      CMD_BUFFER_SIZE : natural :=        32; -- # of chars in the command buffer
1027
      WATCHDOG_VALUE  : natural :=       200; -- # of sys_clks before ack is expected
1028
      DISPLAY_FIELDS  : natural :=         8  -- # of fields/line
1029
    );
1030
    port (
1031
 
1032
      sys_rst_n    : in  std_logic;
1033
      sys_clk      : in  std_logic;
1034
      sys_clk_en   : in  std_logic;
1035
 
1036
      -- rate and parity
1037
      parity_i     : in  unsigned(1 downto 0); -- 0=none, 1=even, 2=odd
1038
      baud_clk_i   : in  std_logic; -- At 1x the desired baud rate, can be squarewave or pulses.
1039
      baud_lock_i  : in  std_logic; -- '1' Indicates baud clock is stable and ready.
1040
 
1041
      -- Serial IO
1042
      cmd_i        : in  std_logic;
1043
      resp_o       : out std_logic;
1044
      cmd_done_o   : out std_logic;
1045
 
1046
      -- Master Bus IO
1047
      master_bg_i  : in  std_logic;
1048
      master_adr_i : in  unsigned(4*ADR_DIGITS-1 downto 0);
1049
      master_dat_i : in  unsigned(4*DAT_DIGITS-1 downto 0);
1050
      master_dat_o : out unsigned(4*DAT_DIGITS-1 downto 0);
1051
      master_stb_i : in  std_logic;
1052
      master_we_i  : in  std_logic;
1053
      master_br_o  : out std_logic;
1054
 
1055
      -- System Bus IO
1056
      ack_i        : in  std_logic;
1057
      err_i        : in  std_logic;
1058
      dat_i        : in  unsigned(4*DAT_DIGITS-1 downto 0);
1059
      dat_o        : out unsigned(4*DAT_DIGITS-1 downto 0);
1060
      rst_o        : out std_logic;
1061
      stb_o        : out std_logic;
1062
      cyc_o        : out std_logic;
1063
      adr_o        : out unsigned(4*ADR_DIGITS-1 downto 0);
1064
      we_o         : out std_logic
1065
    );
1066
end async_syscon;
1067
 
1068
architecture beh of async_syscon is
1069
 
1070
-- Constants
1071
constant ENTER_CHAR : unsigned := "00001101";
1072
 
1073
-- Signals
1074
  -- For ascii_syscon
1075
signal cmd_char         : unsigned(7 downto 0);
1076
signal cmd_we_uart      : std_logic;
1077
signal cmd_we_wait      : std_logic;
1078
signal cmd_rx_done      : std_logic;
1079
signal cmd_we           : std_logic;
1080
signal cmd_ack          : std_logic;
1081
signal cmd_echo         : std_logic;
1082
signal resp_char        : unsigned(7 downto 0);
1083
signal resp_cyc         : std_logic;
1084
signal resp_cyc_r1      : std_logic;
1085
signal resp_cyc_uart    : std_logic;
1086
signal resp_ack_uart    : std_logic;
1087
signal resp_ack_uart_r1 : std_logic;
1088
signal resp_ack         : std_logic;
1089
 
1090
  -- For the serial interface
1091
signal async_rx_error       : unsigned(1 downto 0);
1092
signal async_rx_restart     : std_logic;
1093
signal resp_l               : std_logic;
1094
 
1095
----------------------------------------------------------------------------
1096
-- Component Declarations
1097
----------------------------------------------------------------------------
1098
 
1099
----------------------------------------------------------------------------
1100
begin
1101
 
1102
----------------------------------------------------------------------------
1103
-- Instantiations
1104
----------------------------------------------------------------------------
1105
 
1106
uart1 : uart_sqclk
1107
    port map (
1108
 
1109
      sys_rst_n     => sys_rst_n,
1110
      sys_clk       => sys_clk,
1111
      sys_clk_en    => sys_clk_en,
1112
 
1113
      -- rate and parity
1114
      parity_i      => parity_i,
1115
      rate_clk_i    => baud_clk_i,
1116
 
1117
      -- serial I/O
1118
      tx_stream     => resp_l,
1119
      rx_stream     => cmd_i,
1120
 
1121
      --control and status
1122
      tx_wr_i       => resp_cyc_uart,
1123
      tx_dat_i      => resp_char,
1124
      tx_done_o     => resp_ack_uart,
1125
      rx_restart_i  => async_rx_restart,   -- High clears error flags, clears rx_done_o
1126
      rx_dat_o      => cmd_char,
1127
      rx_wr_o       => cmd_we_uart,        -- High pulse means store rx_dat_o.
1128
      rx_done_o     => cmd_rx_done,        -- Remains high after receive, until clk edge with rx_restart_i=1
1129
      frame_err_o   => async_rx_error(0),  -- High = error.  Reset when rx_restart_i asserted.
1130
      parity_err_o  => async_rx_error(1)   -- High = error.  Reset when rx_restart_i asserted.
1131
    );
1132
 
1133
syscon1 : ascii_syscon
1134
    generic map(
1135
      ADR_DIGITS      => ADR_DIGITS, -- # of hex digits for address
1136
      DAT_DIGITS      => DAT_DIGITS, -- # of hex digits for data
1137
      QTY_DIGITS      => QTY_DIGITS, -- # of hex digits for quantity
1138
      CMD_BUFFER_SIZE => CMD_BUFFER_SIZE, -- # of chars in the command buffer
1139
      WATCHDOG_VALUE  => WATCHDOG_VALUE, -- # of sys_clks before ack is expected
1140
      DISPLAY_FIELDS  => DISPLAY_FIELDS -- # of fields/line
1141
    )
1142
    port map(
1143
 
1144
      sys_rst_n    => sys_rst_n,
1145
      sys_clk      => sys_clk,
1146
      sys_clk_en   => sys_clk_en,
1147
 
1148
      -- Parallel ASCII I/O
1149
      cmd_char_i   => cmd_char,
1150
      cmd_we_i     => cmd_we,
1151
      cmd_ack_o    => cmd_ack,
1152
      cmd_echo_o   => cmd_echo,
1153
      resp_char_o  => resp_char,
1154
      resp_cyc_o   => resp_cyc,
1155
      resp_ack_i   => resp_ack,
1156
      cmd_done_o   => cmd_done_o,
1157
 
1158
      -- Master Bus IO
1159
      master_bg_i  => master_bg_i,
1160
      master_adr_i => master_adr_i,
1161
      master_dat_i => master_dat_i,
1162
      master_dat_o => master_dat_o,
1163
      master_stb_i => master_stb_i,
1164
      master_we_i  => master_we_i,
1165
      master_br_o  => master_br_o,
1166
 
1167
      -- System Bus IO
1168
      ack_i        => ack_i,
1169
      err_i        => err_i,
1170
      dat_i        => dat_i,
1171
      dat_o        => dat_o,
1172
      rst_o        => rst_o,
1173
      stb_o        => stb_o,
1174
      cyc_o        => cyc_o,
1175
      adr_o        => adr_o,
1176
      we_o         => we_o
1177
    );
1178
 
1179
----------------------------------------------------------------------------
1180
-- Module code
1181
----------------------------------------------------------------------------
1182
 
1183
async_rx_restart <= async_rx_error(0) or async_rx_error(1) or cmd_ack;
1184
resp_o <= resp_l when cmd_echo='0' else
1185
          cmd_i  when ECHO_COMMANDS/=0 else
1186
          '1';
1187
 
1188
  -- Detect rising edge of resp_ack_uart
1189
  resp_ack_proc: Process(sys_rst_n,sys_clk)
1190
  begin
1191
    if (sys_rst_n = '0') then
1192
      resp_ack_uart_r1 <= '1';
1193
    elsif (sys_clk'event AND sys_clk='1') then
1194
      if (sys_clk_en='1') then
1195
        resp_ack_uart_r1 <= resp_ack_uart;
1196
      end if;
1197
    end if; -- sys_clk
1198
  end process;
1199
  resp_ack <= '1' when resp_ack_uart='1' and resp_ack_uart_r1='0' else '0';
1200
 
1201
  -- Detect rising edge of resp_cyc
1202
  resp_cyc_proc: Process(sys_rst_n,sys_clk)
1203
  begin
1204
    if (sys_rst_n = '0') then
1205
      resp_cyc_r1 <= '1';
1206
    elsif (sys_clk'event AND sys_clk='1') then
1207
      if (sys_clk_en='1') then
1208
        resp_cyc_r1 <= resp_cyc;
1209
      end if;
1210
    end if; -- sys_clk
1211
  end process;
1212
  resp_cyc_uart <= '1' when resp_cyc='1' and resp_cyc_r1='0' else '0';
1213
 
1214
  -- Create a valid command write enable, that waits until the final echoed
1215
  -- character (CHAR_ENTER) is done being transmitted
1216
  cmd_we_proc: Process(sys_rst_n,sys_clk)
1217
  begin
1218
    if (sys_rst_n = '0') then
1219
      cmd_we_wait <= '0';
1220
    elsif (sys_clk'event AND sys_clk='1') then
1221
      if (sys_clk_en='1') then
1222
        if (cmd_we_uart='1' and cmd_we_wait='0') then
1223
          cmd_we_wait <= '1';
1224
        end if;
1225
        if (cmd_we_wait='1') then
1226
          if (cmd_rx_done='1') then
1227
            cmd_we_wait <= '0';
1228
          end if;
1229
        end if;
1230
      end if;
1231
    end if; -- sys_clk
1232
  end process;
1233
 
1234
cmd_we <= cmd_we_uart when baud_lock_i='1' and cmd_char/=ENTER_CHAR else
1235
          '1'         when baud_lock_i='1' and cmd_char=ENTER_CHAR and cmd_we_wait='1' and cmd_rx_done='1' else
1236
          '0';
1237
 
1238
end beh;
1239
 
1240
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.