ETISS 0.11.2
ExtendableTranslatingInstructionSetSimulator(version0.11.2)
Loading...
Searching...
No Matches
InterruptHandler.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-3-Clause
2//
3// This file is part of ETISS. It is licensed under the BSD 3-Clause License; you may not use this file except in
4// compliance with the License. You should have received a copy of the license along with this project. If not, see the
5// LICENSE file.
17#include "etiss/jit/ReturnCode.h"
18
19using namespace etiss;
20
22 std::shared_ptr<CPUArch> arch, InterruptType itype, bool sync)
23 : itype_(itype), sync_(sync), vector_(interruptVector), enable_(interruptEnable), cpuarch_(arch)
24{
25 empty_ = true;
26}
27
29
30bool interrupt_handler_cmp(const std::pair<etiss::uint64, std::pair<unsigned, bool>> &o1,
31 const std::pair<etiss::uint64, std::pair<unsigned, bool>> &o2)
32{
33 return o1.first < o2.first;
34}
35
36void InterruptHandler::setLine(unsigned line, bool state, etiss::uint64 time_ps)
37{
38 if (vector_ == 0)
39 return;
40
41 if (sync_)
42 mu_.lock();
43 pending_.push_back(std::make_pair(time_ps, std::make_pair(line, state))); // add interrupt to list
45 empty_ = false;
46 if (sync_)
47 mu_.unlock();
48}
49
51{
52 etiss::uint64 time_ps = plugin_cpu_->cpuTime_ps;
53
54 if (vector_ == 0)
55 return etiss::RETURNCODE::NOERROR;
56
57 if (sync_)
58 mu_.lock();
59
60 bool mayinterrupt = (itype_ != EDGE_TRIGGERED); // edge triggered may only interrupt once after a rising edge
61
62 // if (itype_ == EDGE_TRIGGERED) {
63 // for (int i=0; i < vector_->width() * 8; ++i) {
64 // if (vector_->getBit(i)) {
65 // std::cout << "clearing\n";
66 // vector_->setBit(i, 0);
67 // }
68 // }
69 // }
70
71 // fast check for empty pending list
72 if (!empty_)
73 {
74
75 while (!pending_.empty() && pending_.front().first <= time_ps)
76 { // apply events from past
77 std::pair<etiss::uint64, std::pair<unsigned, bool>> &cur = pending_.front();
78
79 switch (itype_)
80 {
81 case EDGE_TRIGGERED:
82 if (cur.second.second)
83 { // if line high
84 if (ed_raised_.find(cur.second.first) == ed_raised_.end())
85 { // if line was low
86 ed_raised_.insert(cur.second.first);
87 mayinterrupt = true;
88 }
89 }
90 else
91 { // line low
92 ed_raised_.erase(cur.second.first);
93 }
94
95 vector_->setBit(cur.second.first, cur.second.second);
96 break;
97 case LEVEL_TRIGGERED:
98 // dont need to clear state in case of iss model (i.e. if not using interrupt listener plugin)
99 if (!cur.second.second && !vector_->consumed_by_interruptlistener_)
100 {
101 break;
102 }
103 vector_->setBit(cur.second.first, cur.second.second);
104 break;
105 default:
106 std::cout << "InterruptHandler::execute: ERROR: interrupt type is invalid" << stream_code_info
107 << std::endl;
108 }
109 pending_.pop_front();
110
111 // only handle one pending event in case of edge-triggered events
112 if (itype_ == EDGE_TRIGGERED && mayinterrupt)
113 {
114 break;
115 }
116 // only handle one pending event in case of level-triggered events
117 if (itype_ == LEVEL_TRIGGERED)
118 {
119 break;
120 }
121 }
122
123 empty_ = pending_.empty();
124 }
125
126 if (sync_)
127 mu_.unlock();
128
129 auto active = vector_->isActive();
130 auto enabled = enable_->isEnabled();
131
132 // std::cout << "active: " << active << ", enabled: " << enabled << std::endl;
133
134 return (mayinterrupt && active && enabled) ? etiss::RETURNCODE::INTERRUPT : etiss::RETURNCODE::NOERROR;
135}
136
138{
139 return "InterruptHandler";
140}
bool interrupt_handler_cmp(const std::pair< etiss::uint64, std::pair< unsigned, bool > > &o1, const std::pair< etiss::uint64, std::pair< unsigned, bool > > &o2)
interrupt checking and signaling
defines a general interface to set interrupt bits
#define stream_code_info
Definition types.h:41
virtual std::string _getPluginName() const
InterruptHandler(etiss::InterruptVector *interruptVector, etiss::InterruptEnable *interruptEnable, std::shared_ptr< etiss::CPUArch > arch, InterruptType itype=EDGE_TRIGGERED, bool sync=true)
std::set< unsigned > ed_raised_
virtual etiss::int32 execute()
apply interrupt changes to the InterruptVector
std::list< std::pair< etiss::uint64, std::pair< unsigned, bool > > > pending_
list: (time , (line ,state) )
virtual void setLine(unsigned line, bool state, etiss::uint64 time_ps)
set the state of a line at a given time.
const InterruptType itype_
InterruptVector *const vector_
InterruptEnable *const enable_
interface to set interrupt bits
virtual bool isActive() const
virtual void setBit(unsigned bit, bool state)=0
set the bit of an interrupt line to state (true = raised)
ETISS_CPU * plugin_cpu_
holds a pointer to the cpu structure. will be set before init call and after cleanup call
Definition Plugin.h:155
forwards: include/jit/*
Definition Benchmark.h:17
InterruptType
interrupt types supported by the default implementation
etiss_uint64 cpuTime_ps
simulation time of cpu
Definition CPU.h:59