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

Subversion Repositories sd_mmc_emulator

[/] [sd_mmc_emulator/] [trunk/] [rtl/] [async_syscon_pack.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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