1 // Copyright 2017-2019 VMware, Inc.
2 // SPDX-License-Identifier: BSD-2-Clause
3 //
4 // The BSD-2 license (the License) set forth below applies to all parts of the
5 // Cascade project.  You may not use this file except in compliance with the
6 // License.
7 //
8 // BSD-2 License
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are met:
12 //
13 // 1. Redistributions of source code must retain the above copyright notice, this
14 // list of conditions and the following disclaimer.
15 //
16 // 2. Redistributions in binary form must reproduce the above copyright notice,
17 // this list of conditions and the following disclaimer in the documentation
18 // and/or other materials provided with the distribution.
19 //
20 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND
21 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 #ifndef CASCADE_SRC_TARGET_CORE_SW_SW_PAD_H
32 #define CASCADE_SRC_TARGET_CORE_SW_SW_PAD_H
33 
34 #include <cassert>
35 #include <mutex>
36 #include "common/bits.h"
37 #include "target/core.h"
38 
39 namespace cascade::sw {
40 
41 class SwPad : public Pad {
42   public:
43     SwPad(Interface* interface, VId out, size_t size, Bits* val, std::mutex* lock);
44     ~SwPad() override = default;
45 
46     State* get_state() override;
47     void set_state(const State* s) override;
48     Input* get_input() override;
49     void set_input(const Input* i) override;
50 
51     bool overrides_done_step() const override;
52     void done_step() override;
53 
54     void read(VId id, const Bits* b) override;
55     void evaluate() override;
56     bool there_are_updates() const override;
57     void update() override;
58 
59   private:
60     VId out_;
61     size_t size_;
62     Bits* val_;
63     std::mutex* lock_;
64 
65     Bits latch_;
66     bool there_are_updates_;
67 };
68 
SwPad(Interface * interface,VId out,size_t size,Bits * val,std::mutex * lock)69 inline SwPad::SwPad(Interface* interface, VId out, size_t size, Bits* val, std::mutex* lock) : Pad(interface) {
70   out_ = out;
71   size_ = size;
72   val_ = val;
73   lock_ = lock;
74 
75   there_are_updates_ = true;
76   latch_.resize(size);
77 }
78 
get_state()79 inline State* SwPad::get_state() {
80   return new State();
81 }
82 
set_state(const State * s)83 inline void SwPad::set_state(const State* s) {
84   // Stateless; does nothing
85   (void) s;
86 }
87 
get_input()88 inline Input* SwPad::get_input() {
89   // Outputs only; does nothing
90   return new Input();
91 }
92 
set_input(const Input * i)93 inline void SwPad::set_input(const Input* i) {
94   // Outputs only; does nothing
95   (void) i;
96 }
97 
overrides_done_step()98 inline bool SwPad::overrides_done_step() const {
99   return true;
100 }
101 
done_step()102 inline void SwPad::done_step() {
103   there_are_updates_ = true;
104 }
105 
read(VId id,const Bits * b)106 inline void SwPad::read(VId id, const Bits* b) {
107   // Invoking this method doesn't make sense
108   (void) id;
109   (void) b;
110   assert(false);
111 }
112 
evaluate()113 inline void SwPad::evaluate() {
114   interface()->write(out_, &latch_);
115 }
116 
there_are_updates()117 inline bool SwPad::there_are_updates() const {
118   return there_are_updates_;
119 }
120 
update()121 inline void SwPad::update() {
122   there_are_updates_ = false;
123   {
124     std::lock_guard<std::mutex> lg(*lock_);
125     latch_.assign(size_-1, 0, *val_);
126   }
127   evaluate();
128 }
129 
130 } // namespace cascade::sw
131 
132 #endif
133