| | 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 | |