| 1 | [wiki:Component SocLib Components General Index] |
| 2 | |
| 3 | = Component description = |
| 4 | |
| 5 | This component is a caba utility component. |
| 6 | This is a class which |
| 7 | * will handle most of the simple cases of VCI targets |
| 8 | * may handle many segments with different address ranges |
| 9 | * handle atomic operations for you |
| 10 | * will let you define the behaviour through callbacks |
| 11 | |
| 12 | It has a few template parameters: |
| 13 | * VCI parameters, the standart ones |
| 14 | * `default_target`: Whether it will send back an error response if the component is not authoritative for received address |
| 15 | * `support_llsc`: Wheter atomic operations should be supported. |
| 16 | |
| 17 | It has a few instance parameters: |
| 18 | * VCI target port to handle |
| 19 | * List of segments to handle, in the same form that the return value from `getSegmentList()` in the [wiki:Component/MappingTable MappingTable] |
| 20 | * fifo size, the amount of VCI words that may be served in a pipeline fashion |
| 21 | * setting to 1 means only one vci request word will be handled at a time, there will be no pipelining |
| 22 | * setting to more than 1 will enable pipelining |
| 23 | |
| 24 | If default target, this component filters the requests and directly returns an error if address is out of handled segments. |
| 25 | |
| 26 | If atomic operations are enabled, this component filters atomic operations and calls on_write callback only if atomic write is successful. |
| 27 | |
| 28 | = Component usage = |
| 29 | |
| 30 | Let's suppose we implement a VCI target component `MyComponent`. |
| 31 | |
| 32 | Let's have a target VCI port and a FSM handler. |
| 33 | |
| 34 | Let's also have two callbacks for read and write behaviour: |
| 35 | |
| 36 | {{{ |
| 37 | template<typename vci_param> |
| 38 | class MyComponent |
| 39 | : soclib::caba::BaseModule |
| 40 | { |
| 41 | // Import some definitions from vci_param |
| 42 | typedef typename vci_param::addr_t vci_addr_t; |
| 43 | typedef typename vci_param::data_t vci_data_t; |
| 44 | |
| 45 | sc_in<bool> p_resetn; |
| 46 | sc_in<bool> p_clk; |
| 47 | soclib::caba::VciTarget<vci_param> p_vci; |
| 48 | soclib::caba::VciTargetFsm<vci_param> m_vci_fsm; |
| 49 | |
| 50 | // Callbacks, see below for parameters' meanings |
| 51 | bool on_write( size_t seg, vci_addr_t addr, vci_data_t data, int be); |
| 52 | bool on_read( size_t seg, vci_addr_t addr, vci_data_t &data ); |
| 53 | |
| 54 | void transition(); |
| 55 | void genMoore(); |
| 56 | |
| 57 | ... |
| 58 | |
| 59 | public: |
| 60 | MyComponent( |
| 61 | sc_module_name name, |
| 62 | const soclib::common::MappingTable &mt, |
| 63 | const soclib::common::IntTab &ident ); |
| 64 | }; |
| 65 | }}} |
| 66 | |
| 67 | == Initialization == |
| 68 | |
| 69 | In the constructor, we must initialize the target fsm and its callbacks: |
| 70 | |
| 71 | {{{ |
| 72 | template <typename vci_param> |
| 73 | MyComponent<vci_param>::MyComponent( |
| 74 | sc_module_name name, |
| 75 | const soclib::common::MappingTable &mt, |
| 76 | const soclib::common::IntTab &ident ) |
| 77 | : p_resetn("resetn"), |
| 78 | p_clk("clk"), |
| 79 | p_vci("vci"), // Constructor for the vci port, give it a name |
| 80 | m_vci_fsm(p_vci, mt.getSegmentList(ident), 1), // Constructor for the FSM, with 1 request served at a time |
| 81 | ... // other constructors |
| 82 | { |
| 83 | // Constructor code |
| 84 | // Set callbacks |
| 85 | m_vci_fsm.on_read_write(on_read, on_write); |
| 86 | |
| 87 | // Like any other Caba module: |
| 88 | SC_METHOD(transition); |
| 89 | dont_initialize(); |
| 90 | sensitive << p_clk.pos(); |
| 91 | |
| 92 | SC_METHOD(genMoore); |
| 93 | dont_initialize(); |
| 94 | sensitive << p_clk.neg(); |
| 95 | } |
| 96 | }}} |
| 97 | |
| 98 | Now for transition and Moore generation, we must also call the fsm: |
| 99 | |
| 100 | {{{ |
| 101 | template <typename vci_param> |
| 102 | void MyComponent<vci_param>::transition() |
| 103 | { |
| 104 | if ( ! p_resetn.read() ) { |
| 105 | m_vci_fsm.reset(); |
| 106 | // Other code specific to MyComponent |
| 107 | return; |
| 108 | } |
| 109 | |
| 110 | m_vci_fsm.transition(); |
| 111 | |
| 112 | // Other code specific to MyComponent |
| 113 | } |
| 114 | |
| 115 | template <typename vci_param> |
| 116 | void MyComponent<vci_param>::genMoore() |
| 117 | { |
| 118 | m_vci_fsm.genMoore(); |
| 119 | |
| 120 | // Other code specific to MyComponent |
| 121 | } |
| 122 | }}} |
| 123 | |
| 124 | == Callbacks == |
| 125 | |
| 126 | === On read function === |
| 127 | |
| 128 | This function is called when a read request comes from VCI port. |
| 129 | |
| 130 | If the request is a multi-word request, callback will be called once per word. |
| 131 | |
| 132 | {{{bool on_read( size_t seg, vci_addr_t addr, vci_data_t &data )}}} |
| 133 | |
| 134 | return value:: |
| 135 | true if this request is valid, false if not. If false, an error value is returned in response packet for this word. |
| 136 | seg:: |
| 137 | index of the served segment in the list passed in constructor. As segments caracteristics are copied, you may retrieve them with other functions, see below |
| 138 | addr:: |
| 139 | offset in segment, this value is the vci-requested address minus the hit segment base address. |
| 140 | data:: |
| 141 | data value to return in response packet |
| 142 | |
| 143 | === On write function === |
| 144 | |
| 145 | This function is called when a write request comes from VCI port. |
| 146 | |
| 147 | If the request is a multi-word request, callback will be called once per word. |
| 148 | |
| 149 | {{{bool on_write(size_t seg, vci_addr_t addr, vci_data_t data, int be)}}} |
| 150 | |
| 151 | return value:: |
| 152 | true if this request is valid, false if not. If false, an error value is returned in response packet for this word. |
| 153 | seg:: |
| 154 | index of the served segment in the list passed in constructor. As segments caracteristics are copied, you may retrieve them with other functions, see below |
| 155 | addr:: |
| 156 | offset in segment, this value is the vci-requested address minus the hit segment base address. |
| 157 | data:: |
| 158 | data value received in the command packet |
| 159 | be:: |
| 160 | byte-enable field from the request |
| 161 | |
| 162 | == Other functions == |
| 163 | |
| 164 | `getSize( size_t segment_index )`:: |
| 165 | get the size of the handled segment |
| 166 | `getBase( size_t segment_index )`:: |
| 167 | get the base address of the handled segment |
| 168 | `getEnd( size_t segment_index )`:: |
| 169 | get the end address of the handled segment (addresses above are not valid for this segment) |
| 170 | `getName( size_t segment_index )`:: |
| 171 | get the name of the handled segment, for debugging purposes |
| 172 | `nbSegments()`:: |
| 173 | get the cardinal of handled segments set |
| 174 | `currentSourceId()`:: |
| 175 | get the srcid of the currently served request |
| 176 | |