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

Subversion Repositories p9813_rgb_led_string_driver

[/] [p9813_rgb_led_string_driver/] [trunk/] [rtl/] [VHDL/] [testbench/] [sim_control_port_pack.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jclaytons
--------------------------------------------------------------------------
2
-- Package of simulation control port components
3
--
4
 
5
library IEEE;
6
use IEEE.STD_LOGIC_1164.ALL;
7
use IEEE.NUMERIC_STD.ALL;
8
 
9
package sim_control_port_pack is
10
 
11
  component sim_uart_control_port
12
  generic(
13
    INPUT_FILE     :  string;
14
    OUTPUT_FILE    :  string;
15
    POR_DURATION   :    time;  -- Duration of internal reset signal activity
16
    POR_ASSERT_LOW : boolean;  -- Determine polarity of reset signal
17
    CLKRATE        : integer;  -- Control Port clock rate default.
18
    UART_BAUDRATE  : integer;  -- UART Speed, in bits per second.
19
    UART_PARITY    : integer;  -- ODD parity
20
    LINE_LENGTH    : integer   -- Length of buffer to hold file input bytes
21
  );
22
  port(
23
    test_rst : out std_logic;
24
    test_clk : out std_logic;
25
    uart_tx  : out std_logic;  -- async. Serial line to FPGA
26
    uart_rx  : in  std_logic   -- async. Serial line from FPGA
27
  );
28
  end component;
29
 
30
  component sim_bus_control_port
31
  generic(
32
    -- relating to file I/O
33
    INPUT_FILE      :  string;
34
    OUTPUT_FILE     :  string;
35
    POR_DURATION    :    time;  -- Duration of internal reset signal activity
36
    POR_ASSERT_LOW  : boolean;  -- Determine polarity of reset signal
37
    CLKRATE         : integer;  -- Control Port clock rate
38
    LINE_LENGTH     : integer;  -- Length of buffer to hold file input bytes
39
    -- relating to the bus controller
40
    ADR_DIGITS      : natural; -- # of hex digits for address
41
    DAT_DIGITS      : natural; -- # of hex digits for data
42
    QTY_DIGITS      : natural; -- # of hex digits for quantity
43
    CMD_BUFFER_SIZE : natural; -- # of chars in the command buffer
44
    WATCHDOG_VALUE  : natural; -- # of sys_clks before ack is expected
45
    DISPLAY_FIELDS  : natural  -- # of fields/line
46
  );
47
  port(
48
    -- Clock and reset stimulus
49
    test_rst : out std_logic;
50
    test_clk : out std_logic;
51
 
52
    -- System Bus IO
53
    ack_i    : in  std_logic;
54
    err_i    : in  std_logic;
55
    dat_i    : in  unsigned(4*DAT_DIGITS-1 downto 0);
56
    dat_o    : out unsigned(4*DAT_DIGITS-1 downto 0);
57
    rst_o    : out std_logic;
58
    stb_o    : out std_logic;
59
    cyc_o    : out std_logic;
60
    adr_o    : out unsigned(4*ADR_DIGITS-1 downto 0);
61
    we_o     : out std_logic
62
  );
63
  end component;
64
 
65
 
66
end sim_control_port_pack;
67
 
68
package body sim_control_port_pack is
69
end sim_control_port_pack;
70
 
71
-------------------------------------------------------------------------------
72
-- Simulation UART ASCII Control Port
73
-------------------------------------------------------------------------------
74
--
75
-- Author: John Clayton
76
-- Date  : Jan. 02, 2014 Transferred component into package file, wrote
77
--                       short description.
78
--
79
-- Description
80
-------------------------------------------------------------------------------
81
-- This is a component meant for simulation only.  It allows commands to be
82
-- read in from a file, parsed, and characters representing the desired
83
-- command are then sent out in asynchronous serial form, via a UART.
84
--
85
-- There is a delay specified with each command in the input file, which
86
-- determines how much time elapses between the current command and the
87
-- subsequent one.  Care must therefore be exercised when setting up the
88
-- simulation command input file, since commands which do not have
89
-- sufficient delay can cause subsequent commands to be ignored.
90
--
91
--   DESCRIPTION OF STIMULUS FILE I/O
92
--   --------------------------------
93
-- The stimulus file I/O introduces a "wrapper" around the characters which are fed
94
-- as stimulus into the command processor of the bus controller.  This is done so that
95
-- each command, after being issued, can be followed up with the requested delay before
96
-- issuing the next command.  Also, the structure of the stimulus input file contains
97
-- provisions for different types of stimulus, although only the 'd' and 'b' types are
98
-- implemented here:
99
--
100
--   'u' type = UART bus command with delay
101
--
102
-- The related module, "sim_bus_control_port" uses the 'b' type:
103
--
104
--   'b' type = binary bus command with delay
105
--   'd' type = delay only; no command
106
--
107
-- The line is terminated with one of these characters:
108
--   ';' (Sends a Carriage Return, 0x0D)
109
--   '\' (Sends an Escape character, 0x1B)
110
--   '-' (Sends a Carriage Return, and ignores the remainder of the line as a comment)
111
 
112
 
113
library IEEE ;
114
use IEEE.STD_LOGIC_1164.all;
115
use IEEE.NUMERIC_STD.all;
116
 
117
library std ;
118
use std.textio.all;
119
 
120
library work;
121
use work.function_pack.all;
122
use work.uart_sqclk_pack.all;
123
use work.sim_support_pack.all;
124
 
125
entity sim_uart_control_port is
126
  generic(
127
    INPUT_FILE     : string  := ".\uart_sim_in.txt";
128
    OUTPUT_FILE    : string  := ".\uart_sim_out.txt";
129
    POR_DURATION   :   time  :=    500 ns;  -- Duration of internal reset signal activity
130
    POR_ASSERT_LOW : boolean :=     false;  -- Determines polarity of reset output
131
    CLKRATE        : integer := 100000000;  -- Control Port clock rate default.
132
    UART_BAUDRATE  : integer :=    921600;  -- UART Speed, in bits per second.
133
    UART_PARITY    : integer :=         2;  -- ODD parity
134
    LINE_LENGTH    : integer :=        40   -- Length of buffer to hold file input bytes
135
  );
136
  port(
137
    test_rst : out std_logic;  -- Programmable polarity
138
    test_clk : out std_logic;  -- Programmable frequency
139
    uart_tx  : out std_logic;  -- HS async. Serial line to FPGA
140
    uart_rx  : in  std_logic   -- HS async. Serial line from FPGA
141
  );
142
end sim_uart_control_port;
143
 
144
architecture beh of sim_uart_control_port is
145
 
146
---- Constants
147
constant BS_CHAR_U : unsigned(7 downto 0) := str2u("08",8);
148
constant CR_CHAR_U : unsigned(7 downto 0) := str2u("0D",8);
149
constant LF_CHAR_U : unsigned(7 downto 0) := str2u("0A",8);
150
constant ES_CHAR_U : unsigned(7 downto 0) := str2u("1B",8); -- Escape character
151
 
152
---- Components
153
 
154
---- State Machine
155
TYPE   TST_STATE_TYPE IS (IDLE, UART_TX_OP);
156
signal tst_state        : TST_STATE_TYPE;
157
 
158
---- Stimulus related signals
159
type   cmd_bytes_array is array (integer range 0 to LINE_LENGTH-1) of unsigned(7 downto 0);
160
signal cmd_bytes    : cmd_bytes_array;
161
signal cmd_byte_cnt : integer;
162
signal tx_length    : integer;
163
signal new_stim     : boolean := false;
164
signal stim_kind    : character;
165
 
166
-- Internal signals
167
signal ctlr_test_clk_i  : std_logic := '0';
168
signal nhreset_internal : std_logic := '0';
169
 
170
  -- Clock generator signals
171
signal uart_dds_phase  : unsigned(15 downto 0);
172
signal uart_clk        : std_logic;
173
 
174
  -- UART signals
175
signal tx_wr       : std_logic;
176
signal tx_data     : unsigned(7 downto 0);
177
signal tx_done     : std_logic;
178
signal tx_done_qld : std_logic; -- Qualified tx_done, stays low when tx_wr is high.
179
signal rx_wr       : std_logic;
180
signal rx_data     : unsigned(7 downto 0);
181
signal rx_done     : std_logic;
182
signal parity      : unsigned(1 downto 0);  -- Parity setting.
183
signal uart_rate   : unsigned(15 downto 0); -- Bit rate setting.
184
 
185
 
186
BEGIN
187
 
188
  test_clk    <= ctlr_test_clk_i;
189
 
190
  -------------------------
191
  -- Controller Clock Process
192
  -- Generates the Control Port clock
193
  ctlr_clk : process
194
    variable PS_PER_SECOND : real := 1.0E+12;
195
    variable half_period : time := integer(PS_PER_SECOND/(2.0*real(CLKRATE))) * 1 ps;
196
  begin
197
     --wait for 1/2 of the clock period;
198
     wait for half_period;
199
     ctlr_test_clk_i <= not (ctlr_test_clk_i);
200
  end process;
201
 
202
-------------------------
203
-- Reset Process
204
-- Causes reset to go inactive after a given time.
205
  rst_gen : process
206
  begin
207
    wait for POR_DURATION; -- Maybe wait long enough for the PLL to lock...
208
    nhreset_internal <= '1';
209
  end process;
210
  test_rst <= nhreset_internal when (POR_ASSERT_LOW) else not nhreset_internal;
211
 
212
-------------------------
213
-- Stimulus Process
214
-- Reads text input file and forms stimulus needed for the simulation.
215
  stim_proc: process(ctlr_test_clk_i, nhreset_internal)
216
    file s_file : text is in INPUT_FILE;
217
    variable time_mark    : time := 0 ns; -- Last NOW time when file IO was parsed
218
    variable time_val     : time := 0 ns; -- Relative time of next file IO parsing.
219
    variable line_1       : line;
220
    variable line_2       : line;
221
    variable item_count   : integer;
222
    variable line_num     : integer;
223
    variable line_done    : boolean;
224
    variable stim_done    : boolean;
225
    variable good         : boolean;
226
    variable temp_char    : character;
227
    variable stim_kind_v  : character; -- variable version readable immediately in display_stim
228
    variable cmd_found    : boolean;
229
    variable dchar_i      : integer;
230
 
231
    -- returns true is the character is a valid hexadecimal character.
232
    function is_hex(c : character) return boolean is
233
    begin
234
      case c is
235
        when '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' |
236
             'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'a' | 'b' | 'c' | 'd' |
237
             'e' | 'f' =>
238
          return(true);
239
        when others =>
240
          return(false);
241
      end case;
242
    end is_hex;
243
 
244
    -- This prints the time and type of stimulus
245
    procedure display_stim is
246
    begin
247
      if (temp_char/='-') then
248
        write (line_2, string'(" [line "));
249
        write (line_2, line_num);
250
        write (line_2, string'(", at "));
251
        write (line_2, now, unit => ns);
252
        write (line_2, string'("]"));
253
        writeline (output, line_2);
254
      end if;
255
    end display_stim;
256
 
257
  begin
258
    if (nhreset_internal='0') then
259
      tx_length <= 0;
260
      line_num := 0;
261
    elsif (ctlr_test_clk_i'event and ctlr_test_clk_i = '1') then
262
      -- Default Values
263
      new_stim <= false;
264
      if (tst_state/=IDLE) then
265
        new_stim <= false;
266
      end if;
267
      -- Simulation Stimulus
268
      if (NOW > (time_val+time_mark)) then
269
        if not(endfile(s_file)) then
270
          readline(s_file, line_1);
271
          line_num   := line_num+1;
272
          stim_done  := false;
273
          cmd_found  := false;
274
          item_count := 0;
275
          stim_kind   <= 'z'; -- Default
276
          stim_kind_v := 'z';
277
          if (line_1'length=0) then
278
            line_done := true;
279
          else
280
            line_done  := false;
281
          end if;
282
          while (line_done = false) loop
283
            read(line_1, temp_char, good);
284
            if (temp_char = '-' or temp_char = ';' or temp_char = '\') then
285
              line_done := true;
286
            elsif (item_count=0 and temp_char/=' ') then
287
              stim_kind   <= temp_char;
288
              stim_kind_v := temp_char; -- Display stim uses this.  It cannot read stim_kind immediately.
289
              if (stim_kind_v='u') then
290
                write(line_2,string'("UART Command: "));
291
              elsif (stim_kind_v='d') then
292
                write(line_2,string'("UART Delay Token. "));
293
              else
294
                write(line_2,string'("UART Unknown stimulus type encountered.  No action taken."));
295
              end if;
296
              item_count  := item_count+1;
297
            elsif (item_count=1) then -- Time field read removes leading whitespace automatically.
298
              time_val := 0 ns;
299
              read(line_1, time_val);
300
              time_mark := NOW;
301
              item_count := item_count+1;
302
            end if;
303
            if (stim_kind_v='u') then
304
              if (item_count>1 and not line_done) then
305
                if (cmd_found) then
306
                  cmd_bytes(item_count-2) <= asciichar2u(temp_char);
307
                  write(line_2, temp_char); -- Keep record of cmd characters for display
308
                  item_count := item_count+1;
309
                else
310
                  if not is_space(temp_char) then
311
                    cmd_found := true;
312
                    cmd_bytes(item_count-2) <= asciichar2u(temp_char);
313
                    write(line_2, temp_char); -- Keep record of cmd characters for display
314
                    item_count := item_count+1;
315
                  end if;
316
                end if;
317
              elsif (item_count>1 and temp_char=';') then
318
                cmd_bytes(item_count-2) <= CR_CHAR_U;
319
                item_count := item_count+1;
320
              elsif (item_count>1 and temp_char='\') then
321
                cmd_bytes(item_count-2) <= ES_CHAR_U;
322
                item_count := item_count+1;
323
              end if;
324
            end if;
325
            if (good=false) then
326
              line_done := true;
327
            end if;
328
          end loop;
329
          if (stim_kind_v='u') then
330
            tx_length <= item_count-2;
331
            new_stim <= true;
332
          end if;
333
          display_stim;
334
        elsif not (stim_done) then
335
          write (line_2, string'("At "));
336
          write (line_2, now, unit => ns);
337
          write (line_2, string'(", UART control port finished reading stimulus file. "));
338
          writeline (output, line_2);
339
          stim_done := true;
340
        end if;
341
      end if;
342
    end if;
343
 
344
  end process;
345
 
346
-------------------------
347
-- Response Record Process
348
  response_proc: process(ctlr_test_clk_i)
349
    file o_file : text is out OUTPUT_FILE;
350
    variable line_1       : line;
351
    variable line_2       : line;
352
    variable good         : boolean;
353
    variable header_done  : boolean := false;
354
 
355
  begin
356
    if not header_done then
357
      write (line_2, string'("Simulation Results File"));
358
      writeline (o_file, line_2);
359
      header_done := true;
360
    end if;
361
    if (ctlr_test_clk_i'event and ctlr_test_clk_i = '1') then
362
      if (rx_wr='1') then
363
        if (rx_data=BS_CHAR_U) then
364
          write (line_2, string'("<BS>"));
365
        elsif (rx_data=CR_CHAR_U) then
366
          write (line_2, string'("<CR>"));
367
        elsif (rx_data=LF_CHAR_U) then
368
          write (line_2, string'("<LF>"));
369
          writeline (o_file, line_2);
370
--          write (line_2, string'("At "));
371
--          write (line_2, now, justified => RIGHT, field => 12, unit => us);
372
--          write (line_2, string'(", received line feed."));
373
--          writeline (o_file, line_2);
374
        else
375
--          write (line_2, u2string(rx_data,2)); -- For Hexadecimal output
376
          write (line_2, u2asciichar(rx_data)); -- For ASCII output
377
        end if;
378
      end if;
379
    end if;
380
 
381
  end process;
382
 
383
-------------------------
384
-- Control Port State Machine
385
-- For async., loads and awaits TX completion for the three TLM bytes.
386
-- For CMD, simply starts the transmitter and waits for completion.
387
  cp_fsm_proc: process(ctlr_test_clk_i, nhreset_internal)
388
  begin
389
    if (nhreset_internal='0') then
390
      tst_state  <= IDLE;
391
      tx_wr      <= '0';
392
      tx_data    <= (others=>'0');
393
      cmd_byte_cnt   <= 0;
394
    elsif (ctlr_test_clk_i'event and ctlr_test_clk_i = '1') then
395
      -- Default Values
396
      tx_wr      <= '0';
397
      tx_data    <= (others=>'0');
398
      case tst_state is
399
 
400
        when IDLE =>
401
          cmd_byte_cnt <= 0;
402
          if (new_stim) then
403
            if (stim_kind='u') then
404
              tst_state <= UART_TX_OP;
405
            end if;
406
          end if;
407
 
408
        when UART_TX_OP =>         -- Send out the bytes
409
          if (tx_done_qld = '1') then
410
            if (cmd_byte_cnt = tx_length) then
411
              cmd_byte_cnt <= 0;
412
              tst_state <= IDLE;
413
            else
414
              tx_wr   <= '1';
415
              cmd_byte_cnt <= cmd_byte_cnt+1;
416
              tx_data <= cmd_bytes(cmd_byte_cnt);
417
            end if;
418
          end if;
419
 
420
      end case;
421
    end if;                                      -- end if(FPGA_CLK = 1)
422
  end process;
423
 
424
  tx_done_qld <= (tx_done and not tx_wr);
425
 
426
-------------------------
427
-- UART without buffer
428
  tst_uart: entity work.uart_sqclk
429
    port map (
430
 
431
      sys_rst_n     => nhreset_internal,
432
      sys_clk       => ctlr_test_clk_i,
433
      sys_clk_en    => '1',
434
 
435
      -- rate and parity
436
      parity_i      => parity,
437
      rate_clk_i    => uart_clk,
438
 
439
      -- serial I/O
440
      tx_stream     => uart_tx,
441
      rx_stream     => uart_rx,
442
 
443
      --control and status
444
      tx_wr_i       => tx_wr,
445
      tx_dat_i      => tx_data,
446
      tx_done_o     => tx_done,
447
      rx_restart_i  => '0',
448
      rx_dat_o      => rx_data,
449
      rx_wr_o       => rx_wr,
450
      rx_done_o     => rx_done,
451
      frame_err_o   => open,
452
      parity_err_o  => open
453
    );
454
 
455
  -- UART settings
456
  parity    <= to_unsigned(UART_PARITY,parity'length);
457
  uart_rate <= to_unsigned(integer(real(2**16)*real(UART_BAUDRATE)/real(CLKRATE)),16);
458
 
459
  -------------------------
460
  -- UART Clock Process
461
  uart_dds: process(nhreset_internal,ctlr_test_clk_i)
462
  begin
463
    if (nhreset_internal = '0') then
464
      uart_dds_phase   <= (others=>'0');
465
    elsif (ctlr_test_clk_i'event and ctlr_test_clk_i='1') then
466
      uart_dds_phase <= uart_dds_phase + uart_rate;
467
    end if;
468
  end process uart_dds;
469
  uart_clk <= uart_dds_phase(15);
470
 
471
 
472
end beh;
473
 
474
 
475
 
476
 
477
---------------------------------------------------------------------------------------
478
-- Bus Controller for simulation use
479
---------------------------------------------------------------------------------------
480
--
481
-- Author: John Clayton
482
-- Date  : Dec. 27, 2013
483
-- Update: 12/27/13 Copied code from async_syscon_pack.vhd, Wrote some description
484
--                  Began merging in file I/O code from "uart_ascii_control_port_sim.vhd"
485
--
486
-- Description
487
---------------------------------------------------------------------------------------
488
-- This Bus Controller for simulation use combines a "ascii_syscon" module with a
489
-- "uart_ascii_control_port_sim" module, resulting in a single module that can use
490
-- file I/O for stimulus input and response output, while providing the parameterized
491
-- capabilities of the async_syscon module.  The purpose for combining these modules
492
-- is to eliminate the serial interface between them, thereby dramatically decreasing
493
-- simulation run times.
494
--
495
--   DESCRIPTION OF STIMULUS FILE I/O
496
--   --------------------------------
497
-- The stimulus file I/O introduces a "wrapper" around the characters which are fed
498
-- as stimulus into the command processor of the bus controller.  This is done so that
499
-- each command, after being issued, can be followed up with the requested delay before
500
-- issuing the next command.  Also, the structure of the stimulus input file contains
501
-- provisions for different types of stimulus, although only the 'd' and 'b' types are
502
-- implemented here:
503
--
504
--   'b' type = binary bus command with delay
505
--   'd' type = delay only; no command
506
--
507
-- The related module, "sim_uart_control_port" uses the 'u' type:
508
--
509
--   'u' type = UART bus command with delay
510
--
511
--   DESCRIPTION OF ASYNC_SYSCON DERIVED FUNCTIONALITY
512
--   -------------------------------------------------
513
-- This is a state-machine driven parallel 8-bit ASCII character interface to a "Wishbone"
514
-- type of bus.  It is intended to be used as a "Wishbone system controller"
515
-- for debugging purposes.  Specifically, the unit allows the user to send
516
-- text commands to the unit, in order to generate read and
517
-- write cycles on the Wishbone compatible bus.  The command structure is
518
-- quite terse and spartan in nature, this is for the sake of the logic itself.
519
-- Because the menu-driven command structure is supported without the use of
520
-- dedicated memory blocks (in order to maintain cross-platform portability
521
-- as much as possible) the menus and command responses were kept as small
522
-- as possible.  In most cases, the responses from the unit to the user
523
-- consist of a "newline" and one or two visible characters.  The command
524
-- structure consists of the following commands and responses:
525
--
526
-- Command Syntax              Purpose
527
-- ---------------             ---------------------------------------
528
-- w aaaa dddd dddd dddd...    Write data items "dddd" starting at address "aaaa"
529
--                             using sequential addresses.
530
--                             (If the data field is missing, nothing is done).
531
-- w0 aaaa dddd dddd dddd...   Write data items "dddd" at address "aaaa"
532
--                             without incrementing the address.
533
--                             (If the data field is missing, nothing is done).
534
-- f aaaa dddd xx              "Fill": Write data "dddd" starting at address "aaaa"
535
--                             perform this "xx" times at sequential addresses.
536
--                             (The quantity field is optional, default is 1).
537
-- f0 aaaa dddd xx             "Fill": Write data "dddd" starting at address "aaaa"
538
--                             perform this "xx" times at the same address.
539
--                             (The quantity field is optional, default is 1).
540
-- r aaaa xx                   Read data starting from address "aaaa."
541
--                             Perform this "xx" times at sequential addresses.
542
--                             (The quantity field is optional, default is 1).
543
-- r0 aaaa xx                  Read data from address "aaaa."
544
--                             Perform this "xx" times, using the same address.
545
--                             (The quantity field is optional, default is 1).
546
-- i                           Send a reset pulse to the system. (initialize).
547
--
548
-- <COMMENT_CHAR>              "Single Line" type Comment token.  Characters
549
--                             after the token are ignored until <ENTER>.
550
--                             This enables applications which send
551
--                             files to the unit to include comments for
552
--                             display and as an aid to understanding.
553
--                             The comment token is a constant, change it
554
--                             to be whatever makes sense!
555
--
556
-- Response from               Meaning
557
-- --------------------------  ---------------------------------------
558
-- OK                          Command received and performed.  No errors.
559
-- ?                           Command buffer full, without receiving "enter."
560
-- C?                          Command not recognized.
561
-- A?                          Address field syntax error.
562
-- D?                          Data field syntax error.
563
-- Q?                          Quantity field syntax error.
564
-- !                           No "ack_i", or else "err_i" received from bus.
565
-- B!                          No "bg_i" received from master.
566
--
567
-- NOTES on the operation of this unit:
568
--
569
-- - The unit generates a command prompt which is "-> ".
570
-- - Capitalization is not important.
571
-- - Each command is terminated by the "enter" key (0x0d character).
572
--   Commands are executed as soon as "enter" is received.
573
-- - Trailing parameters need not be re-entered.  Their values will
574
--   remain the same as their previous settings.
575
-- - Use of the backspace key is supported, so mistakes can be corrected.
576
-- - The length of the command line is limited to a fixed number of
577
--   characters, as configured by parameter.
578
-- - Fields are separated by white space, including "tab" and/or "space"
579
-- - All numerical fields are interpreted as hexadecimal numbers.
580
--   Decimal is not supported.
581
-- - Numerical field values are retained between commands.  If a "r" is issued
582
--   without any fields following it, the previous values will be used.  A
583
--   set of "quantity" reads will take place at sequential addresses.
584
--   If a "f" is issued without any fields following it, the previous data
585
--   value will be written "quantity" times at sequential addresses, starting
586
--   from the next location beyond where the last command ended.
587
-- - If the user does not wish to use "ack" functionality, simply tie the
588
--   "ack_i" input to logic 1, and then the ! response will never be generated.
589
-- - The data which is read in by the "r" command is displayed using lines
590
--   which begin with the address, followed by the data fields.  The number
591
--   of data fields displayed per line (following the address) is adjustable
592
--   by setting a parameter.  No other display format adjustments can be made.
593
-- - There is currently only a single watchdog timer.  It begins to count at
594
--   the time the "enter" is received to execute a command.  If the bus is granted
595
--   and the ack is received before the expiration of the timer, then the
596
--   cycle will complete normally.  Therefore, the watchdog timeout value
597
--   needs to include time for the request and granting of the bus, in
598
--   addition to the time needed for the actual bus cycle to complete.
599
--
600
--
601
-- Currently, there is only a single indicator (stb_o) generated during bus
602
-- output cycles which are generated from this unit.
603
-- The user can easily implement decoding logic based upon adr_o and stb_o
604
-- which would serve as multiple "stb_o" type signals for different cores
605
-- which would be sharing the same bus.
606
--
607
-- The data bus supported by this module is separate input/output type of bus.
608
-- However, if a single tri-state dat_io bus is desired, it can be added
609
-- to the module without too much trouble.  Supposedly the only difference
610
-- between the two forms of data bus is that one of them avoids using tri-state
611
-- at the cost of doubling the number of interconnects used to carry data back
612
-- and forth...  Some people say that tri-state should be avoided for use
613
-- in internal busses in ASICs.  Maybe they are right.
614
-- But in FPGAs tri-state seems to work pretty well, even for internal busses.
615
--
616
-- Parameters are provided to configure the width of the different command
617
-- fields.  To simplify the logic for binary to hexadecimal conversion, these
618
-- parameters allow adjustment in units of 1 hex digit, not anything smaller.
619
-- If your bus has 10 bits, for instance, simply set the address width to 3
620
-- which produces 12 bits, and then just don't use the 2 msbs of address
621
-- output.
622
--
623
-- No support for the optional Wishbone "retry" (rty_i) input is provided at
624
-- this time.
625
-- No support for "tagn_o" bits is provided at this time, although a register
626
-- might be added external to this module in order to implement to tag bits.
627
-- No BLOCK or RMW cycles are supported currently, so cyc_o is equivalent to
628
-- stb_o...
629
-- The output busses are not tri-stated.  The user may add tri-state buffers
630
-- external to the module, using "stb_o" to enable the buffer outputs.
631
--
632
---------------------------------------------------------------------------------------
633
 
634
library IEEE ;
635
use IEEE.STD_LOGIC_1164.all;
636
use IEEE.NUMERIC_STD.all;
637
 
638
library std ;
639
use std.textio.all;
640
 
641
library work;
642
use work.function_pack.all;
643
use work.sim_support_pack.all;
644
use work.async_syscon_pack.all;
645
 
646
entity sim_bus_control_port is
647
  generic (
648
    -- relating to file I/O
649
    INPUT_FILE      : string  := ".\bus_sim_in.txt";
650
    OUTPUT_FILE     : string  := ".\bus_sim_out.txt";
651
    POR_DURATION    :   time  :=    500 ns;  -- Duration of internal reset signal activity
652
    POR_ASSERT_LOW  : boolean :=     false;  -- Determines polarity of reset output
653
    CLKRATE         : integer := 100000000;  -- Control Port clock rate default.
654
    LINE_LENGTH     : integer :=        40;  -- Length of buffer to hold file input bytes
655
    -- relating to the bus controller
656
    ADR_DIGITS      : natural :=         4; -- # of hex digits for address
657
    DAT_DIGITS      : natural :=         4; -- # of hex digits for data
658
    QTY_DIGITS      : natural :=         2; -- # of hex digits for quantity
659
    CMD_BUFFER_SIZE : natural :=        32; -- # of chars in the command buffer
660
    WATCHDOG_VALUE  : natural :=       200; -- # of sys_clks before ack is expected
661
    DISPLAY_FIELDS  : natural :=         8  -- # of fields/line
662
  );
663
  port(
664
    -- Clock and reset stimulus
665
    test_rst : out std_logic;  -- Programmable polarity
666
    test_clk : out std_logic;  -- Programmable frequency
667
 
668
    -- System Bus IO
669
    ack_i    : in  std_logic;
670
    err_i    : in  std_logic;
671
    dat_i    : in  unsigned(4*DAT_DIGITS-1 downto 0);
672
    dat_o    : out unsigned(4*DAT_DIGITS-1 downto 0);
673
    rst_o    : out std_logic;
674
    stb_o    : out std_logic;
675
    cyc_o    : out std_logic;
676
    adr_o    : out unsigned(4*ADR_DIGITS-1 downto 0);
677
    we_o     : out std_logic
678
  );
679
end sim_bus_control_port;
680
 
681
architecture beh of sim_bus_control_port is
682
-- File I/O Constants
683
constant BS_CHAR_U : unsigned(7 downto 0) := str2u("08",8);
684
constant CR_CHAR_U : unsigned(7 downto 0) := str2u("0D",8);
685
constant LF_CHAR_U : unsigned(7 downto 0) := str2u("0A",8);
686
 
687
-- File I/O Signals
688
-------------------
689
---- State Machine
690
TYPE   TST_STATE_TYPE IS (IDLE, CMD_CHAR_OP);
691
signal tst_state        : TST_STATE_TYPE;
692
 
693
---- Stimulus related signals
694
type   cmd_bytes_array is array (integer range 0 to LINE_LENGTH-1) of unsigned(7 downto 0);
695
signal cmd_bytes    : cmd_bytes_array;
696
signal cmd_byte_cnt : integer := 0;
697
signal tx_length    : integer;
698
signal new_stim     : boolean := false;
699
signal stim_kind    : character;
700
 
701
-- Internal signals
702
signal ctlr_test_clk_i  : std_logic := '0';
703
signal nhreset_internal : std_logic := '0';
704
 
705
-- System Controller Signals
706
signal cmd_char         : unsigned(7 downto 0);
707
signal cmd_we           : std_logic;
708
signal cmd_ack          : std_logic;
709
signal cmd_echo         : std_logic;
710
signal resp_char        : unsigned(7 downto 0);
711
signal resp_cyc         : std_logic;
712
signal resp_ack         : std_logic;
713
 
714
---------------------------------------------------------------------------------------
715
begin
716
 
717
-- File I/O Logic Statements
718
 
719
  test_clk    <= ctlr_test_clk_i;
720
 
721
  -------------------------
722
  -- Controller Clock Process
723
  -- Generates the Control Port clock
724
  ctlr_clk : process
725
    variable PS_PER_SECOND : real := 1.0E+12;
726
    variable half_period : time := integer(PS_PER_SECOND/(2.0*real(CLKRATE))) * 1 ps;
727
  begin
728
     --wait for 1/2 of the clock period;
729
     wait for half_period;
730
     ctlr_test_clk_i <= not (ctlr_test_clk_i);
731
  end process;
732
 
733
-------------------------
734
-- Reset Process
735
-- Causes reset to go inactive after a given time.
736
  rst_gen : process
737
  begin
738
    wait for POR_DURATION; -- Maybe wait long enough for the PLL to lock...
739
    nhreset_internal <= '1';
740
  end process;
741
  test_rst <= nhreset_internal when (POR_ASSERT_LOW) else not nhreset_internal;
742
 
743
-------------------------
744
-- Stimulus Process
745
-- Reads text input file and forms stimulus needed for the simulation.
746
  stim_proc: process(ctlr_test_clk_i, nhreset_internal)
747
    file s_file : text is in INPUT_FILE;
748
    variable time_mark    : time := 0 ns; -- Last NOW time when file IO was parsed
749
    variable time_val     : time := 0 ns; -- Relative time of next file IO parsing.
750
    variable line_1       : line;
751
    variable line_2       : line;
752
    variable item_count   : integer;
753
    variable line_num     : integer;
754
    variable line_done    : boolean;
755
    variable stim_done    : boolean;
756
    variable good         : boolean;
757
    variable temp_char    : character;
758
    variable stim_kind_v  : character; -- variable version readable immediately in display_stim
759
    variable cmd_found    : boolean;
760
 
761
    -- returns true is the character is a valid hexadecimal character.
762
    function is_hex(c : character) return boolean is
763
    begin
764
      case c is
765
        when '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' |
766
             'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'a' | 'b' | 'c' | 'd' |
767
             'e' | 'f' =>
768
          return(true);
769
        when others =>
770
          return(false);
771
      end case;
772
    end is_hex;
773
 
774
    -- This prints the time and type of stimulus
775
    procedure display_stim is
776
    begin
777
      if (temp_char/='-') then
778
        write (line_2, string'(" [line "));
779
        write (line_2, line_num);
780
        write (line_2, string'(", at "));
781
        write (line_2, now, unit => ns);
782
        write (line_2, string'("]"));
783
        writeline (output, line_2);
784
      end if;
785
    end display_stim;
786
 
787
  begin
788
    if (nhreset_internal='0') then
789
      tx_length <= 0;
790
      line_num := 0;
791
    elsif (ctlr_test_clk_i'event and ctlr_test_clk_i = '1') then
792
      -- Default Values
793
      new_stim <= false;
794
      if (tst_state/=IDLE) then
795
        new_stim <= false;
796
      end if;
797
      -- Simulation Stimulus
798
      if (NOW > (time_val+time_mark)) then
799
        if not(endfile(s_file)) then
800
          readline(s_file, line_1);
801
          line_num := line_num+1;
802
          stim_done  := false;
803
          cmd_found  := false;
804
          item_count := 0;
805
          stim_kind   <= 'z'; -- Default
806
          stim_kind_v := 'z';
807
          if (line_1'length=0) then
808
            line_done := true;
809
          else
810
            line_done  := false;
811
          end if;
812
          while (line_done = false) loop
813
            read(line_1, temp_char, good);
814
            if (temp_char = '-' or temp_char = ';') then
815
              line_done := true;
816
            elsif (item_count=0 and temp_char/=' ') then
817
              stim_kind   <= temp_char;
818
              stim_kind_v := temp_char; -- Display stim uses this.  It cannot read stim_kind immediately.
819
              if (stim_kind_v='b') then
820
                write (line_2, string'("Bus Command: "));
821
              elsif (stim_kind_v='d') then
822
                write (line_2, string'("Bus delay token. "));
823
              else
824
                write (line_2, string'("Bus unknown stimulus type encountered. No Action. "));
825
              end if;
826
              item_count  := item_count+1;
827
            elsif (item_count=1) then -- Time field read removes leading whitespace automatically.
828
              time_val := 0 ns;
829
              read(line_1, time_val);
830
              time_mark := NOW;
831
              item_count := item_count+1;
832
            end if;
833
            if (stim_kind_v='b') then
834
              if (item_count>1 and not line_done) then
835
                if (cmd_found) then
836
                  cmd_bytes(item_count-2) <= asciichar2u(temp_char);
837
                  write(line_2, temp_char); -- Keep record of cmd characters for display
838
                  item_count := item_count+1;
839
                else
840
                  if not is_space(temp_char) then
841
                    cmd_found := true;
842
                    cmd_bytes(item_count-2) <= asciichar2u(temp_char);
843
                    write(line_2, temp_char); -- Keep record of cmd characters for display
844
                    item_count := item_count+1;
845
                  end if;
846
                end if;
847
              elsif (item_count>1 and temp_char=';') then
848
                cmd_bytes(item_count-2) <= CR_CHAR_U;
849
                item_count := item_count+1;
850
              end if;
851
            end if;
852
            if (good=false) then
853
              line_done := true;
854
            end if;
855
          end loop;
856
          if (stim_kind_v='b') then
857
            tx_length <= item_count-2;
858
            new_stim <= true;
859
          end if;
860
          display_stim;
861
        elsif not (stim_done) then
862
          write (line_2, string'("At "));
863
          write (line_2, now, unit => ns);
864
          write (line_2, string'(", Bus control port finished reading stimulus file. "));
865
          writeline (output, line_2);
866
          stim_done := true;
867
        end if;
868
      end if;
869
    end if;
870
 
871
  end process;
872
 
873
-------------------------
874
-- Response Record Process
875
  response_proc: process(ctlr_test_clk_i)
876
    file o_file : text is out OUTPUT_FILE;
877
    variable line_1       : line;
878
    variable line_2       : line;
879
    variable good         : boolean;
880
    variable header_done  : boolean := false;
881
 
882
  begin
883
    if not header_done then
884
      write (line_2, string'("Simulation Results File"));
885
      writeline (o_file, line_2);
886
      header_done := true;
887
    end if;
888
    if (ctlr_test_clk_i'event and ctlr_test_clk_i = '1') then
889
      if (cmd_echo='1' and cmd_ack='1') then
890
        if (cmd_char=BS_CHAR_U) then
891
          write (line_2, string'("<BS>"));
892
        elsif (cmd_char=CR_CHAR_U) then
893
          write (line_2, string'("<CR>"));
894
        elsif (cmd_char=LF_CHAR_U) then
895
          write (line_2, string'("<LF>"));
896
          writeline (o_file, line_2);
897
        else
898
--          write (line_2, u2string(cmd_char,2)); -- For Hexadecimal output
899
          write (line_2, u2asciichar(cmd_char)); -- For ASCII output
900
        end if;
901
      elsif (cmd_echo='0' and resp_ack='1') then
902
        if (resp_char=BS_CHAR_U) then
903
          write (line_2, string'("<BS>"));
904
        elsif (resp_char=CR_CHAR_U) then
905
          write (line_2, string'("<CR>"));
906
        elsif (resp_char=LF_CHAR_U) then
907
          write (line_2, string'("<LF>"));
908
          writeline (o_file, line_2);
909
        else
910
--          write (line_2, u2string(resp_char,2)); -- For Hexadecimal output
911
          write (line_2, u2asciichar(resp_char)); -- For ASCII output
912
        end if;
913
      end if;
914
    end if;
915
 
916
  end process;
917
 
918
  resp_ack <= resp_cyc;
919
 
920
-------------------------
921
-- Control Port State Machine
922
  cp_fsm_proc: process(ctlr_test_clk_i, nhreset_internal)
923
  begin
924
    if (nhreset_internal='0') then
925
      tst_state      <= IDLE;
926
      cmd_byte_cnt   <= 0;
927
    elsif (ctlr_test_clk_i'event and ctlr_test_clk_i = '1') then
928
      -- Default Values
929
 
930
      -- State machine
931
      case tst_state is
932
 
933
        when IDLE =>
934
          cmd_byte_cnt <= 0;
935
          if (new_stim) then
936
            if (stim_kind='b') then
937
              tst_state <= CMD_CHAR_OP;
938
            end if;
939
          end if;
940
 
941
        when CMD_CHAR_OP => -- Send Command Character
942
          if (cmd_ack='1') then
943
            cmd_byte_cnt <= cmd_byte_cnt+1;
944
          else
945
            cmd_byte_cnt <= 0;
946
            tst_state <= IDLE;
947
          end if;
948
 
949
      end case;
950
    end if;                                      -- end if(FPGA_CLK = 1)
951
  end process;
952
 
953
  cmd_char <= cmd_bytes(cmd_byte_cnt);
954
  cmd_we <= '1' when tst_state=CMD_CHAR_OP and cmd_byte_cnt<tx_length else '0';
955
 
956
syscon1 : entity work.ascii_syscon
957
    generic map(
958
      ADR_DIGITS      => ADR_DIGITS, -- # of hex digits for address
959
      DAT_DIGITS      => DAT_DIGITS, -- # of hex digits for data
960
      QTY_DIGITS      => QTY_DIGITS, -- # of hex digits for quantity
961
      CMD_BUFFER_SIZE => CMD_BUFFER_SIZE, -- # of chars in the command buffer
962
      WATCHDOG_VALUE  => WATCHDOG_VALUE, -- # of sys_clks before ack is expected
963
      DISPLAY_FIELDS  => DISPLAY_FIELDS -- # of fields/line
964
    )
965
    port map(
966
 
967
      sys_rst_n    => nhreset_internal,
968
      sys_clk      => ctlr_test_clk_i,
969
      sys_clk_en   => '1',
970
 
971
      -- Parallel ASCII I/O
972
      cmd_char_i   => cmd_char,
973
      cmd_we_i     => cmd_we,
974
      cmd_ack_o    => cmd_ack,
975
      cmd_echo_o   => cmd_echo,
976
      resp_char_o  => resp_char,
977
      resp_cyc_o   => resp_cyc,
978
      resp_ack_i   => resp_ack,
979
      cmd_done_o   => open,
980
 
981
      -- Master Bus IO
982
      master_bg_i  => '1',
983
      master_adr_i => to_unsigned(0,4*ADR_DIGITS),
984
      master_dat_i => to_unsigned(0,4*DAT_DIGITS),
985
      master_dat_o => open,
986
      master_stb_i => '0',
987
      master_we_i  => '0',
988
      master_br_o  => open,
989
 
990
      -- System Bus IO
991
      ack_i        => ack_i,
992
      err_i        => err_i,
993
      dat_i        => dat_i,
994
      dat_o        => dat_o,
995
      rst_o        => rst_o,
996
      stb_o        => stb_o,
997
      cyc_o        => cyc_o,
998
      adr_o        => adr_o,
999
      we_o         => we_o
1000
    );
1001
 
1002
 
1003
 
1004
end beh;
1005
 

powered by: WebSVN 2.1.0

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