ECE 448 Lecture 17 Developing User MMIO Cores

  • Slides: 65
Download presentation
ECE 448 Lecture 17 Developing User MMIO Cores & Drivers George Mason University

ECE 448 Lecture 17 Developing User MMIO Cores & Drivers George Mason University

Required Reading P. Chu, FPGA Prototyping by VHDL Examples 10. 3 MMIO I/O core

Required Reading P. Chu, FPGA Prototyping by VHDL Examples 10. 3 MMIO I/O core 10. 4 Timer core development 10. 5. 3 Vanilla MMIO subsystem 10. 7 Vanilla FPro system construction 12. 4 Sampler FPro system 3

Motivation – Lab 4 (1) Random Pattern Generator The game should use a 9

Motivation – Lab 4 (1) Random Pattern Generator The game should use a 9 -bit Linear Feedback Shift Register (LFSR), implemented in hardware. This LFSR should be used in combination with the reset and start buttons to generate a truly random pattern of lights at the beginning of each game. The implemented LFSR should have the length L=9, the period 29 -1=511, and be set by the reset button to a non-zero state. BTND is used to interrupt puzzle solving and return to the initial state, thus it is also referred to as a reset button. 4

Motivation – Lab 4 (2) The LFSR shown in Fig. 1 fulfills all three

Motivation – Lab 4 (2) The LFSR shown in Fig. 1 fulfills all three mentioned above conditions. After the reset button is pressed, the value of LFSR should change every clock period of the 100 MHz clock, i. e. , every 10 ns. When the start button (BTNC) is pressed, the current value of the LFSR output should be used to determine the initial pattern of lights. 5

Developing an MMIO user core & the corresponding driver Conceptual Design: C 1. Specification

Developing an MMIO user core & the corresponding driver Conceptual Design: C 1. Specification of the core C 2. I/O register map of the IP core Hardware Design: H 1. Basic circuit with the required functionality H 2. A wrapper matching the interface of an MMIO core H 3. Instantiating the core in the FPro System Software Design: S 1. Software driver • class definition (. h) • class implementation (. cpp) • test program (. cpp) S 2. Integration with the main application (. cpp) 6

Developing an MMIO user core & the corresponding driver Conceptual Design: C 1. Specification

Developing an MMIO user core & the corresponding driver Conceptual Design: C 1. Specification of the core C 2. I/O register map of the IP core Hardware Design: H 1. Basic circuit with the required functionality H 2. A wrapper matching the interface of an MMIO core H 3. Instantiating the core in the FPro System Software Design: S 1. Software driver • class definition (. h) • class implementation (. cpp) • test program (. cpp) S 2. Integration with the main application (. cpp) 7

User Core • 48 -bit counter value • The processor interacts with the counter

User Core • 48 -bit counter value • The processor interacts with the counter as follows: § retrieve (i. e. , read) the counter value. § set or reset (i. e. , write) a “go” signal to resume or pause the counting. § generate (i. e. , write) a “clear” pulse to clear the counter to 0.

Developing an MMIO user core & the corresponding driver Conceptual Design: C 1. Specification

Developing an MMIO user core & the corresponding driver Conceptual Design: C 1. Specification of the core C 2. I/O register map of the IP core Hardware Design: H 1. Basic circuit with the required functionality H 2. A wrapper matching the interface of an MMIO core H 3. Instantiating the core in the FPro System Software Design: S 1. Software driver • class definition (. h) • class implementation (. cpp) • test program (. cpp) S 2. Integration with the main application (. cpp)

IO Register Map of the User Core 10

IO Register Map of the User Core 10

Developing an MMIO core & the corresponding driver Conceptual Design: C 1. Specification of

Developing an MMIO core & the corresponding driver Conceptual Design: C 1. Specification of the core C 2. I/O register map of the IP core Hardware Design: H 1. Basic circuit with the required functionality H 2. A wrapper matching the interface of an MMIO core H 3. Instantiating the core in the FPro System Software Design: S 1. Software driver • class definition (. h) • class implementation (. cpp) • test program (. cpp) S 2. Integration with the main application (. cpp)

Basic circuit with the required functionality go 12

Basic circuit with the required functionality go 12

Developing an MMIO core & the corresponding driver Conceptual Design: C 1. Specification of

Developing an MMIO core & the corresponding driver Conceptual Design: C 1. Specification of the core C 2. I/O register map of the IP core Hardware Design: H 1. Basic circuit with the required functionality H 2. A wrapper matching the interface of an MMIO core H 3. Instantiating the core in the FPro System Software Design: S 1. Software driver • class definition (. h) • class implementation (. cpp) • test program (. cpp) S 2. Integration with the main application (. cpp)

Required Interface of Every MMIO Core Optional ports for the communication with the I/O

Required Interface of Every MMIO Core Optional ports for the communication with the I/O devices on the board 14

Interface of the User MMIO Core 15

Interface of the User MMIO Core 15

Basic circuit with the required functionality go 16

Basic circuit with the required functionality go 16

IO Register Map of the Timer Core cs write read addr(1: 0) wr_data(1: 0)

IO Register Map of the Timer Core cs write read addr(1: 0) wr_data(1: 0) Operation 1 00 −− Read lower word 1 01 −− Read upper word 1 1 0 10 01 Set “go” signal 1 1 0 10 00 Reset “go” signal 1 1 0 10 1− Set “clear” signal 17

A wrapper matching the required interface go cs write read addr(1: 0) wr_data(1: 0)

A wrapper matching the required interface go cs write read addr(1: 0) wr_data(1: 0) Operation 1 00 −− Read lower word 1 01 −− Read upper word 1 1 0 10 01 Set “go” signal 1 1 0 10 00 Reset “go” signal 1 1 0 10 1− Set “clear” signal 18

User Core in VHDL (1) library ieee; use ieee. std_logic_1164. all; use ieee. numeric_std.

User Core in VHDL (1) library ieee; use ieee. std_logic_1164. all; use ieee. numeric_std. all; entity user_core is port( clk : in std_logic; reset : in std_logic; -- slot interface cs : in std_logic; write : in std_logic; read : in std_logic; addr : in std_logic_vector(4 downto 0); rd_data : out std_logic_vector(31 downto 0); wr_data : in std_logic_vector(31 downto 0) ); end user_core; 19

User Core in VHDL (2) architecture mixed of user_core is signal count_reg : unsigned(47

User Core in VHDL (2) architecture mixed of user_core is signal count_reg : unsigned(47 downto 0); signal count_next : unsigned(47 downto 0); signal ctrl_reg : std_logic; signal wr_en : std_logic; signal clear, go : std_logic; begin --********************************* -- counter --********************************* -- register process(clk, reset) begin if reset = '1' then count_reg <= (others => '0'); elsif (clk'event and clk = '1') then count_reg <= count_next; end if; end process; 20

User Core in VHDL (3) -- next-state logic count_next <= (others => '0') when

User Core in VHDL (3) -- next-state logic count_next <= (others => '0') when clear = '1' else count_reg + 1 when go = '1' else count_reg; -- ctrl register process(clk, reset) begin if reset = '1' then ctrl_reg <= '0'; elsif (clk'event and clk = '1') then if wr_en = '1' then ctrl_reg <= wr_data(0); end if; end process; 21

User Core in VHDL (4) -- decoding logic wr_en <= '1' when write='1' and

User Core in VHDL (4) -- decoding logic wr_en <= '1' when write='1' and cs='1' and addr(1 downto 0)="10" else '0'; clear <= '1' when wr_en='1' and wr_data(1)='1' else '0'; go <= ctrl_reg; -- slot read multiplexing rd_data <= std_logic_vector(count_reg(31 downto 0)) when addr(0)='0' else x"0000" & std_logic_vector(count_reg(47 downto 32)); end mixed; 22

Developing an MMIO core & the corresponding driver Conceptual Design: C 1. Specification of

Developing an MMIO core & the corresponding driver Conceptual Design: C 1. Specification of the core C 2. I/O register map of the IP core Hardware Design: H 1. Basic circuit with the required functionality H 2. A wrapper matching the interface of an MMIO core H 3. Instantiating the core in the FPro System Software Design: S 1. Software driver • class definition (. h) • class implementation (. cpp) • test program (. cpp) S 2. Integration with the main application (. cpp)

User tx rx GPO 2 GPI 2 24 LEDs Switches SSEG Buttons

User tx rx GPO 2 GPI 2 24 LEDs Switches SSEG Buttons

User tx rx GPO 2 GPI 2 25 LEDs Switches SSEG Buttons

User tx rx GPO 2 GPI 2 25 LEDs Switches SSEG Buttons

Source Code – Hardware Core: chu_mcs_bridge. vhd [do not modify] chu_io_map. vhd Path to

Source Code – Hardware Core: chu_mcs_bridge. vhd [do not modify] chu_io_map. vhd Path to the core: In the Sampler FPro System on the ECE 448 website: sampler_example_src/hw/hdl/fpro_src/hdl/sys/bridge In fpga_mcs_vhdl_src. zip downloaded from the textbook companion website: fpga_mcs_vhdl_src/hdl/sys/bridge 26

chu_io_map. vhd -- ********************************* -- slot definition for the "sampler" MMIO subsystem -- avoid

chu_io_map. vhd -- ********************************* -- slot definition for the "sampler" MMIO subsystem -- avoid changing the first four slots -- ********************************* constant S 0_SYS_TIMER : integer : = 0; constant S 1_UART 1 : integer : = 1; constant S 2_LED : integer : = 2; constant S 3_SW : integer : = 3; constant S 4_USER : integer : = 4; constant S 5_XADC : integer : = 5; constant S 6_PWM : integer : = 6; constant S 7_BTN : integer : = 7; constant S 8_SSEG : integer : = 8; constant S 9_SPI : integer : = 9; constant S 10_I 2 C : integer : = 10; constant S 11_PS 2 : integer : = 11; constant S 12_DDFS : integer : = 12; constant S 13_ADSR : integer : = 13; 27

mmio_sys_sampler_basys 3 User tx rx GPO 2 GPI 2 28 LEDs Switches SSEG Buttons

mmio_sys_sampler_basys 3 User tx rx GPO 2 GPI 2 28 LEDs Switches SSEG Buttons

Source Code – Hardware Core: mmio_sys_sampler_basys 3. vhd Path to the core: In the

Source Code – Hardware Core: mmio_sys_sampler_basys 3. vhd Path to the core: In the Sampler FPro System on the ECE 448 website: sampler_example_src/hw/hdl/basys 3_supplement In basys 3_supplement_src. zip downloaded from the textbook companion website: top-level folder 29

mmio_sys_sampler_basys 3. vhd (1) library ieee; use ieee. std_logic_1164. all; use work. chu_io_map. all;

mmio_sys_sampler_basys 3. vhd (1) library ieee; use ieee. std_logic_1164. all; use work. chu_io_map. all; entity mmio_sys_sampler_basys 3 is port( -- FPro bus clk : in std_logic; reset : in std_logic; mmio_cs : in std_logic; mmio_wr : in std_logic; mmio_rd : in std_logic; mmio_addr : in std_logic_vector(20 downto 0); mmio_wr_data : in std_logic_vector(31 downto 0); mmio_rd_data : out std_logic_vector(31 downto 0); -- switches and LEDs sw : in std_logic_vector(15 downto 0); led : out std_logic_vector(15 downto 0); 30

mmio_sys_sampler_basys 3. vhd (2) -- uart rx : in std_logic; tx : out std_logic;

mmio_sys_sampler_basys 3. vhd (2) -- uart rx : in std_logic; tx : out std_logic; -- 4 analog input pair adc_p : in std_logic_vector(3 downto 0); adc_n : in std_logic_vector(3 downto 0); -- pwm : out std_logic_vector(7 downto 0); -- btn : in std_logic_vector(4 downto 0); -- 8 -digit 7 -seg LEDs an : out std_logic_vector(7 downto 0); sseg : out std_logic_vector(7 downto 0); …. . end mmio_sys_sampler_basys 3; 31

mmio_sys_sampler_basys 3. vhd (3) -- slot 0: system timer_slot 0 : entity work. chu_timer

mmio_sys_sampler_basys 3. vhd (3) -- slot 0: system timer_slot 0 : entity work. chu_timer port map( clk => clk, reset => reset, cs => cs_array(S 0_SYS_TIMER), read => mem_rd_array(S 0_SYS_TIMER), write => mem_wr_array(S 0_SYS_TIMER), addr => reg_addr_array(S 0_SYS_TIMER), rd_data => rd_data_array(S 0_SYS_TIMER), wr_data => wr_data_array(S 0_SYS_TIMER) ); 32

chu_io_map. vhd -- ********************************* -- slot definition for the "sampler" MMIO subsystem -- avoid

chu_io_map. vhd -- ********************************* -- slot definition for the "sampler" MMIO subsystem -- avoid changing the first four slots -- ********************************* constant S 0_SYS_TIMER : integer : = 0; constant S 1_UART 1 : integer : = 1; constant S 2_LED : integer : = 2; constant S 3_SW : integer : = 3; constant S 4_USER : integer : = 4; constant S 5_XADC : integer : = 5; constant S 6_PWM : integer : = 6; constant S 7_BTN : integer : = 7; constant S 8_SSEG : integer : = 8; constant S 9_SPI : integer : = 9; constant S 10_I 2 C : integer : = 10; constant S 11_PS 2 : integer : = 11; constant S 12_DDFS : integer : = 12; constant S 13_ADSR : integer : = 13; 33

Interface of Every MMIO Core Optional ports for the communication with the I/O devices

Interface of Every MMIO Core Optional ports for the communication with the I/O devices on the board 34

mmio_sys_sampler_basys 3. vhd (4) -- slot 1: uart 1_slot 1 : entity work. chu_uart

mmio_sys_sampler_basys 3. vhd (4) -- slot 1: uart 1_slot 1 : entity work. chu_uart generic map(FIFO_DEPTH_BIT => 6) port map( clk => clk, reset => reset, cs => cs_array(S 1_UART 1), read => mem_rd_array(S 1_UART 1), write => mem_wr_array(S 1_UART 1), addr => reg_addr_array(S 1_UART 1), rd_data => rd_data_array(S 1_UART 1), wr_data => wr_data_array(S 1_UART 1), -- external signals tx => tx, rx => rx ); 35

mmio_sys_sampler_basys 3. vhd (5) -- slot 2: GPO for 16 LEDs gpo_slot 2 :

mmio_sys_sampler_basys 3. vhd (5) -- slot 2: GPO for 16 LEDs gpo_slot 2 : entity work. chu_gpo generic map(W => 16) port map( clk => clk, reset => reset, cs => cs_array(S 2_LED), read => mem_rd_array(S 2_LED), write => mem_wr_array(S 2_LED), addr => reg_addr_array(S 2_LED), rd_data => rd_data_array(S 2_LED), wr_data => wr_data_array(S 2_LED), -- external signal dout => led ); 36

mmio_sys_sampler_basys 3. vhd (6) -- slot 3: input port for 16 slide switches gpi_slot

mmio_sys_sampler_basys 3. vhd (6) -- slot 3: input port for 16 slide switches gpi_slot 3 : entity work. chu_gpi generic map(W => 16) port map( clk => clk, reset => reset, cs => cs_array(S 3_SW), read => mem_rd_array(S 3_SW), write => mem_wr_array(S 3_SW), addr => reg_addr_array(S 3_SW), rd_data => rd_data_array(S 3_SW), wr_data => wr_data_array(S 3_SW), -- external signal din => sw ); 37

mmio_sys_sampler_basys 3. vhd (7) -- slot 4: reserved for user defined -- user_slot 4

mmio_sys_sampler_basys 3. vhd (7) -- slot 4: reserved for user defined -- user_slot 4 : entity work. -- port map( -- clk => clk, -- reset => reset, -- cs => cs_array(S 4_USER), -- read => mem_rd_array(S 4_USER), -- write => mem_wr_array(S 4_USER), -- addr => reg_addr_array(S 4_USER), -- rd_data => rd_data_array(S 4_USER), -- wr_data => wr_data_array(S 4_USER) -- ); rd_data_array(4) <= (others => '0'); 38

mmio_sys_sampler_basys 3. vhd (7) -- slot 4: user core user_slot 4 : entity work.

mmio_sys_sampler_basys 3. vhd (7) -- slot 4: user core user_slot 4 : entity work. user_core port map( clk => clk, reset => reset, cs => cs_array(S 4_USER), read => mem_rd_array(S 4_USER), write => mem_wr_array(S 4_USER), addr => reg_addr_array(S 4_USER), rd_data => rd_data_array(S 4_USER), wr_data => wr_data_array(S 4_USER) ); -- rd_data_array(4) <= (others => '0'); 39

mmio_sys_sampler_basys 3. vhd (8) -- slot 7: push button debounce_slot 7 : entity work.

mmio_sys_sampler_basys 3. vhd (8) -- slot 7: push button debounce_slot 7 : entity work. chu_debounce_core generic map( W => 5, N => 20 ) port map( clk => clk, -- external interface din => btn reset => reset, ); cs => cs_array(S 7_BTN), read => mem_rd_array(S 7_BTN), write => mem_wr_array(S 7_BTN), addr => reg_addr_array(S 7_BTN), rd_data => rd_data_array(S 7_BTN), wr_data => wr_data_array(S 7_BTN), -- external interface din => btn ); 40

mmio_sys_sampler_basys 3. vhd (9) -- slot 8: 7 -seg LED sseg_led_slot 8 : entity

mmio_sys_sampler_basys 3. vhd (9) -- slot 8: 7 -seg LED sseg_led_slot 8 : entity work. chu_led_mux_core port map( clk => clk, reset => reset, cs => cs_array(S 8_SSEG), read => mem_rd_array(S 8_SSEG), write => mem_wr_array(S 8_SSEG), addr => reg_addr_array(S 8_SSEG), rd_data => rd_data_array(S 8_SSEG), wr_data => wr_data_array(S 8_SSEG), -- external interface an => an, sseg => sseg ); 41

mmio_sys_sampler_basys 3. vhd (10) -- assign 0's to all unused slot rd_data signals gen_unused_slot

mmio_sys_sampler_basys 3. vhd (10) -- assign 0's to all unused slot rd_data signals gen_unused_slot : for i in 14 to 63 generate rd_data_array(i) <= (others => '0'); end generate gen_unused_slot; end arch; 42

Alternative approach: chu_io_map. vhd -- ********************************* -- slot definition for the "sampler" MMIO subsystem

Alternative approach: chu_io_map. vhd -- ********************************* -- slot definition for the "sampler" MMIO subsystem -- avoid changing the first four slots -- ********************************* constant S 0_SYS_TIMER : integer : = 0; constant S 1_UART 1 : integer : = 1; constant S 2_LED : integer : = 2; constant S 3_SW : integer : = 3; constant S 4_USER : integer : = 4; constant S 5_XADC : integer : = 5; constant S 6_PWM : integer : = 6; constant S 7_BTN : integer : = 7; constant S 8_SSEG : integer : = 8; constant S 9_SPI : integer : = 9; constant S 10_I 2 C : integer : = 10; constant S 11_PS 2 : integer : = 11; constant S 12_DDFS : integer : = 12; constant S 13_ADSR : integer : = 13; constant S 14_USER : integer : = 14; 43

Alternative approach: mmio_sys_sampler_basys 3. vhd -- slot 14: user core user_slot 14 : entity

Alternative approach: mmio_sys_sampler_basys 3. vhd -- slot 14: user core user_slot 14 : entity work. user_core port map( clk => clk, reset => reset, cs => cs_array(S 14_USER), read => mem_rd_array(S 14_USER), write => mem_wr_array(S 14_USER), addr => reg_addr_array(S 14_USER), rd_data => rd_data_array(S 14_USER), wr_data => wr_data_array(S 14_USER) ); 44

mmio_sys_sampler_basys 3. vhd (10) -- assign 0's to all unused slot rd_data signals gen_unused_slot

mmio_sys_sampler_basys 3. vhd (10) -- assign 0's to all unused slot rd_data signals gen_unused_slot : for i in 15 to 63 generate rd_data_array(i) <= (others => '0'); end generate gen_unused_slot; end arch; 45

mcs_top_sampler_basys 3 User tx rx GPO 2 GPI 2 46 LEDs Switches SSEG Buttons

mcs_top_sampler_basys 3 User tx rx GPO 2 GPI 2 46 LEDs Switches SSEG Buttons

Source Code – Hardware Core: mcs_top_sampler_basys 3. vhd [do not modify] Path to the

Source Code – Hardware Core: mcs_top_sampler_basys 3. vhd [do not modify] Path to the core: In the Sampler FPro System on the ECE 448 website: sampler_example_src/hw/hdl/basys 3_supplement In basys 3_supplement_src. zip downloaded from the textbook companion website: top-level folder 47

Developing an MMIO core & the corresponding driver Conceptual Design: C 1. Specification of

Developing an MMIO core & the corresponding driver Conceptual Design: C 1. Specification of the core C 2. I/O register map of the IP core Hardware Design: H 1. Basic circuit with the required functionality H 2. A wrapper matching the interface of an MMIO core H 3. Instantiating the core in the FPro System Software Design: S 1. Software driver • class definition (. h) • class implementation (. cpp) • test program (. cpp) S 2. Integration with the main application (. cpp)

Source Code – Software Drivers: chu_io_map. h user_core. cpp Path to the core: In

Source Code – Software Drivers: chu_io_map. h user_core. cpp Path to the core: In the Sampler FPro System on the ECE 448 website: sampler_example_src/sw/drv In fpga_mcs_vhdl_src. zip downloaded from the textbook companion website: fpga_mcs_vhdl_src/cpp/drv 49

Constants Representing Slot Numbers in C/C++ chu_io_map. h #define #define #define #define S 0_SYS_TIMER

Constants Representing Slot Numbers in C/C++ chu_io_map. h #define #define #define #define S 0_SYS_TIMER S 1_UART 1 S 2_LED S 3_SW S 4_USER S 5_XDAC S 6_PWM S 7_BTN S 8_SSEG S 9_SPI S 10_I 2 C S 11_PS 2 S 12_DDFS S 13_ADSR 0 1 2 3 4 5 6 7 8 9 10 11 12 13 50

IO Register Map of the User Core cs write read addr(1: 0) wr_data(1: 0)

IO Register Map of the User Core cs write read addr(1: 0) wr_data(1: 0) Operation 1 00 −− Read lower word 1 01 −− Read upper word 1 1 0 10 01 Set “go” signal 1 1 0 10 00 Reset “go” signal 1 1 0 10 1− Set “clear” signal 51

Timer. Core class definition in user_core. h. (1) #include "chu_io_rw. h" #include "chu_io_map. h"

Timer. Core class definition in user_core. h. (1) #include "chu_io_rw. h" #include "chu_io_map. h" // to obtain system clock rate class User. Core { public: /* register map */ enum { COUNTER_LOWER_REG = 0, // lower 32 bits of counter COUNTER_UPPER_REG = 1, // upper 16 bits of counter CTRL_REG = 2 // control register }; /* masks */ enum { GO_FIELD = 0 x 00000001, // bit 0 of ctrl_reg; enable bit CLR_FIELD = 0 x 00000002 // bit 1 of ctrl_reg; clear bit };

User. Core class definition in user_core. h (2) /* methods */ User. Core(uint 32_t

User. Core class definition in user_core. h (2) /* methods */ User. Core(uint 32_t core_base_addr); // constructor ~User. Core(); // destructor, not used void pause(); void go(); void clear(); uint 64_t read_tick(); uint 64_t read_time(); void sleep(uint 64_t us); private: uint 32_t base_addr; uint 32_t ctrl; }; // pause counter // resume counter // clear the counter to 0 // retrieve # clock cycles elapsed // read time elapsed in microseconds // idle for us microseconds // current state of ctrl_reg

Developing an MMIO core & the corresponding driver Conceptual Design: C 1. Specification of

Developing an MMIO core & the corresponding driver Conceptual Design: C 1. Specification of the core C 2. I/O register map of the IP core Hardware Design: H 1. Basic circuit with the required functionality H 2. A wrapper matching the interface of an MMIO core H 3. Instantiating the core in the FPro System Software Design: S 1. Software driver • class definition (. h) • class implementation (. cpp) • test program (. cpp) S 2. Integration with the main application (. cpp)

User. Core class implementation in user_core. cpp (1) #include "timer_core. h" User. Core: :

User. Core class implementation in user_core. cpp (1) #include "timer_core. h" User. Core: : User. Core(uint 32_t core_base_addr) { base_addr = core_base_addr; ctrl = 0 x 01; clear(); io_write(base_addr, CTRL_REG, ctrl); // enable the timer } User. Core: : ~User. Core() { } void User. Core: : clear() { uint 32_t wdata; // write clear_bit to generate a 1 -clock pulse // clear bit does not affect ctrl wdata = ctrl | CLR_FIELD; io_write(base_addr, CTRL_REG, wdata); }

Timer. Core class implementation in timer_core. cpp (2) void User. Core: : pause() {

Timer. Core class implementation in timer_core. cpp (2) void User. Core: : pause() { // reset enable bit to 0 ctrl = ctrl & ~GO_FIELD; io_write(base_addr, CTRL_REG, ctrl); } void User. Core: : go() { // set enable bit to 1 ctrl = ctrl | GO_FIELD; io_write(base_addr, CTRL_REG, ctrl); } uint 64_t User. Core: : read_tick() { uint 64_t upper, lower; lower = (uint 64_t) io_read(base_addr, COUNTER_LOWER_REG); upper = (uint 64_t) io_read(base_addr, COUNTER_UPPER_REG); return ((upper << 32) | lower); }

Timer. Core class implementation in timer_core. cpp (3) uint 64_t User. Core: : read_time()

Timer. Core class implementation in timer_core. cpp (3) uint 64_t User. Core: : read_time() { // elapsed time in microsecond (SYS_FREQ in MHz) return (read_tick() / SYS_CLK_FREQ); } void User. Core: : sleep(uint 64_t us) { uint 64_t start_time, now; start_time = read_time(); // busy waiting do { now = read_time(); } while ((now - start_time) < us); }

I/O Macros in chu_io_rw. h (1) #ifndef _CHU_IO_RW_H_INCLUDED #define _CHU_IO_RW_H_INCLUDED #include <inttypes. h> //

I/O Macros in chu_io_rw. h (1) #ifndef _CHU_IO_RW_H_INCLUDED #define _CHU_IO_RW_H_INCLUDED #include <inttypes. h> // to use unit. N_t type #ifdef __cplus extern "C" { #endif /*********************************** * generic low-level read and write access * - offset: 32 -bit word offset relative to base * - 4*offset used for byte address * - must bypass data cache for I/O access ***********************************/

I/O Macros in chu_io_rw. h (2) /* Read an io register. * base_addr base

I/O Macros in chu_io_rw. h (2) /* Read an io register. * base_addr base address of an io core * offset register word offset * returns 32 -bit data of the register * macro calculates the byte address of the register and then read */ #define io_read(base_addr, offset) (*(volatile uint 32_t *)((base_addr) + 4*(offset))) /* * Write an io register * base_addr base address of an io core * offset register word offset * data 32 -bit data */ #define io_write(base_addr, offset, data) (*(volatile uint 32_t *)((base_addr) + 4*(offset)) = (data))

Address Map of the MMIO Subsystem 1 word = 4 bytes 1 byte C

Address Map of the MMIO Subsystem 1 word = 4 bytes 1 byte C 0000000 slot 1 30000000 slot 1 211 words … slot 63 MMIO Subsystem 64 slots x 32 words per slot = 26 x 25 words = 211 words 213 bytes … MMIO Subsystem 64 slots x 128 bytes per slot = 26 x 27 words = 213 bytes slot 63

Developing an MMIO core & the corresponding driver Conceptual Design: C 1. Specification of

Developing an MMIO core & the corresponding driver Conceptual Design: C 1. Specification of the core C 2. I/O register map of the IP core Hardware Design: H 1. Basic circuit with the required functionality H 2. A wrapper matching the interface of an MMIO core H 3. Instantiating the core in the FPro System Software Design: S 1. Software driver • class definition (. h) • class implementation (. cpp) • test program (. cpp) S 2. Integration with the main application (. cpp)

main_user_test. cpp (1) #include ". . /drv/chu_init. h" #include ". . /drv/gpio_cores. h" #include

main_user_test. cpp (1) #include ". . /drv/chu_init. h" #include ". . /drv/gpio_cores. h" #include ". . /drv/user_core. h" /** leds blink once per second for 5 times. void user_check(User. Core *user_p, Gpo. Core *led_p) { int i; for (i = 0; i < 5; i++) { led_p->write(0 xffff); user_p->sleep(500000); led_p->write(0 x 0000); user_p->sleep(500000); debug("user check - (loop #)/now: ", i, user->read_time()); } }

main_user_test. cpp (2) int main() { User. Core user(get_slot_addr(BRIDGE_BASE, S 4_USER)); Gpo. Core led(get_slot_addr(BRIDGE_BASE,

main_user_test. cpp (2) int main() { User. Core user(get_slot_addr(BRIDGE_BASE, S 4_USER)); Gpo. Core led(get_slot_addr(BRIDGE_BASE, S 2_LED)); user_check(&user, &led); }

Motivation – Lab 4 (1) Random Pattern Generator The game should use a 9

Motivation – Lab 4 (1) Random Pattern Generator The game should use a 9 -bit Linear Feedback Shift Register (LFSR), implemented in hardware. This LFSR should be used in combination with the reset and start buttons to generate a truly random pattern of lights at the beginning of each game. The implemented LFSR should have the length L=9, the period 29 -1=511, and be set by the reset button to a non-zero state. BTND is used to interrupt puzzle solving and return to the initial state, thus it is also referred to as a reset button. 64

Motivation – Lab 4 (2) The LFSR shown in Fig. 1 fulfills all three

Motivation – Lab 4 (2) The LFSR shown in Fig. 1 fulfills all three mentioned above conditions. After the reset button is pressed, the value of LFSR should change every clock period of the 100 MHz clock, i. e. , every 10 ns. When the start button (BTNC) is pressed, the current value of the LFSR output should be used to determine the initial pattern of lights. 65

Developing an MMIO user core & the corresponding driver Conceptual Design: C 1. Specification

Developing an MMIO user core & the corresponding driver Conceptual Design: C 1. Specification of the core C 2. I/O register map of the IP core Hardware Design: H 1. Basic circuit with the required functionality H 2. A wrapper matching the interface of an MMIO core H 3. Instantiating the core in the FPro System Software Design: S 1. Software driver • class definition (. h) • class implementation (. cpp) • test program (. cpp) S 2. Integration with the main application (. cpp) 66