Browse Source

Implemented basic HiFive1-like platform with PLL,tracing etc.

Eyck Jentzsch 1 year ago
parent
commit
a899d30556

+ 1
- 1
dbt-core

@@ -1 +1 @@
1
-Subproject commit 34abe11e782335ae02dd74a3e47ae8bb366abc25
1
+Subproject commit 31263d4aaa6a7f01914c2decead091dc968f30d3

+ 5
- 2
riscv.sc/incl/sysc/General/system.h View File

@@ -16,14 +16,17 @@ namespace sysc {
16 16
 
17 17
 class system: sc_core::sc_module {
18 18
 public:
19
+    SC_HAS_PROCESS(system);
20
+
19 21
     system(sc_core::sc_module_name nm);
20 22
     virtual ~system();
21 23
 
22
-    sc_core::sc_vector<tlm::tlm_signal<sc_dt::sc_logic>> s_gpio;
23
-
24 24
 private:
25
+    sc_core::sc_vector<tlm::tlm_signal<sc_dt::sc_logic>> s_gpio;
26
+    sc_core::sc_signal<bool> s_rst_n;
25 27
     sysc::platform i_platform;
26 28
     sysc::terminal i_terminal;
29
+    void gen_por();
27 30
 };
28 31
 
29 32
 }

+ 5
- 1
riscv.sc/incl/sysc/SiFive/aon.h View File

@@ -47,13 +47,17 @@ class aon : public sc_core::sc_module, public scc::tlm_target<> {
47 47
 public:
48 48
     SC_HAS_PROCESS(aon);
49 49
     sc_core::sc_in<sc_core::sc_time> clk_i;
50
-    sc_core::sc_in<bool> rst_i;
50
+    sc_core::sc_in<bool> erst_n_i;
51
+    sc_core::sc_out<sc_core::sc_time> lfclkc_o;
52
+    sc_core::sc_out<bool> rst_o;
51 53
     aon(sc_core::sc_module_name nm);
52 54
     virtual ~aon() override; // need to keep it in source file because of fwd declaration of aon_regs
53 55
 
54 56
 protected:
57
+    void start_of_simulation() override;
55 58
     void clock_cb();
56 59
     void reset_cb();
60
+    void reset_internal_cb();
57 61
     sc_core::sc_time clk;
58 62
     std::unique_ptr<aon_regs> regs;
59 63
 };

+ 1
- 0
riscv.sc/incl/sysc/SiFive/core_complex.h View File

@@ -134,6 +134,7 @@ protected:
134 134
     void start_of_simulation();
135 135
     void run();
136 136
     void clk_cb();
137
+    void rst_cb();
137 138
     void sw_irq_cb();
138 139
     void timer_irq_cb();
139 140
     void global_irq_cb();

+ 1
- 1
riscv.sc/incl/sysc/SiFive/gen/prci_regs.h View File

@@ -95,7 +95,7 @@ public:
95 95
 inline sysc::prci_regs::prci_regs(sc_core::sc_module_name nm)
96 96
 : sc_core::sc_module(nm)
97 97
 , NAMED(hfrosccfg, r_hfrosccfg, 0, *this)
98
-, NAMED(hfxosccfg, r_hfxosccfg, 0, *this)
98
+, NAMED(hfxosccfg, r_hfxosccfg, 0x40000000, *this)
99 99
 , NAMED(pllcfg, r_pllcfg, 0, *this)
100 100
 , NAMED(plloutdiv, r_plloutdiv, 0, *this)
101 101
 , NAMED(coreclkcfg, r_coreclkcfg, 0, *this)

+ 5
- 0
riscv.sc/incl/sysc/SiFive/gpio.h View File

@@ -77,8 +77,13 @@ protected:
77 77
     void forward_pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_logic>& gp);
78 78
     void iof_input(unsigned int tag, unsigned iof_idx, tlm::tlm_signal_gp<>& gp, sc_core::sc_time& delay);
79 79
     sc_core::sc_time clk;
80
+    std::array<bool, 32> last_iof0, last_iof1;
80 81
     std::unique_ptr<gpio_regs> regs;
81 82
     std::shared_ptr<sysc::WsHandler> handler;
83
+
84
+private:
85
+    tlm::tlm_phase write_output(tlm::tlm_signal_gp<sc_dt::sc_logic>& gp, size_t i, sc_dt::sc_logic val);
86
+    void enable_outputs(uint32_t new_data);
82 87
 };
83 88
 
84 89
 } /* namespace sysc */

+ 2
- 0
riscv.sc/incl/sysc/SiFive/platform.h View File

@@ -63,6 +63,8 @@ public:
63 63
     sc_core::sc_vector<tlm::tlm_signal_initiator_socket<sc_dt::sc_logic>> pins_o;
64 64
     sc_core::sc_vector<tlm::tlm_signal_target_socket<sc_dt::sc_logic>>    pins_i;
65 65
 
66
+    sc_core::sc_in<bool> erst_n;
67
+
66 68
     platform(sc_core::sc_module_name nm);
67 69
 
68 70
 private:

+ 7
- 4
riscv.sc/incl/sysc/SiFive/prci.h View File

@@ -46,18 +46,21 @@ class prci_regs;
46 46
 class prci : public sc_core::sc_module, public scc::tlm_target<> {
47 47
 public:
48 48
     SC_HAS_PROCESS(prci);
49
-    sc_core::sc_in<sc_core::sc_time> clk_i;
49
+    sc_core::sc_port<sc_core::sc_signal_in_if<sc_core::sc_time>,1,SC_ZERO_OR_MORE_BOUND> hfxosc_i;
50 50
     sc_core::sc_in<bool> rst_i;
51
+    sc_core::sc_out<sc_core::sc_time> hfclk_o;
51 52
     prci(sc_core::sc_module_name nm);
52 53
     virtual ~prci() override; // need to keep it in source file because of fwd declaration of prci_regs
53 54
 
54 55
 protected:
55
-    void clock_cb();
56
+    void hfxosc_cb();
56 57
     void reset_cb();
57 58
     void hfrosc_en_cb();
58
-    sc_core::sc_time clk;
59
+    void hfxosc_en_cb();
60
+    void update_hfclk();
61
+    sc_core::sc_time hfxosc_clk, hfrosc_clk, pll_clk, hfclk;
59 62
     std::unique_ptr<prci_regs> regs;
60
-    sc_core::sc_event hfrosc_en_evt;
63
+    sc_core::sc_event hfrosc_en_evt, hfxosc_en_evt;
61 64
 };
62 65
 
63 66
 } /* namespace sysc */

+ 5
- 5
riscv.sc/src/CMakeLists.txt View File

@@ -3,17 +3,17 @@ FILE(GLOB RiscVSCHeaders *.h */*.h)
3 3
 FILE(GLOB RiscvSCSources sysc/*.cpp)
4 4
 
5 5
 set(LIB_HEADERS ${RiscVSCHeaders} )
6
-set(LIB_SOURCES ${RiscvSCSources}
7
-)
6
+set(LIB_SOURCES ${RiscvSCSources} )
8 7
 
9 8
 set(APP_HEADERS )
10
-
11
-set(APP_SOURCES sc_main.cpp
12
-)
9
+set(APP_SOURCES sc_main.cpp)
13 10
 
14 11
 # Define two variables in order not to repeat ourselves.
15 12
 set(LIBRARY_NAME risc-v.sc)
16 13
 
14
+## the following setting needs to be consistent with the library
15
+#add_definitions(-DSC_DEFAULT_WRITER_POLICY=SC_MANY_WRITERS)
16
+
17 17
 # Define the library
18 18
 add_library(${LIBRARY_NAME} ${LIB_SOURCES})
19 19
 

+ 19
- 5
riscv.sc/src/sc_main.cpp View File

@@ -54,6 +54,16 @@ const size_t SUCCESS = 0;
54 54
 const size_t ERROR_UNHANDLED_EXCEPTION = 2;
55 55
 } // namespace
56 56
 
57
+#include "sysc/kernel/sc_externs.h"
58
+int
59
+main( int argc, char* argv[]){
60
+#ifdef _POSIX_SOURCE
61
+    putenv(const_cast<char*>("SC_SIGNAL_WRITE_CHECK=DISABLE"));
62
+    putenv(const_cast<char*>("SC_VCD_SCOPES=ENABLE"));
63
+#endif
64
+    return sc_core::sc_elab_and_sim( argc, argv );
65
+}
66
+
57 67
 int sc_main(int argc, char *argv[]) {
58 68
     //    sc_report_handler::set_handler(my_report_handler);
59 69
     scc::Logger<>::reporting_level() = logging::ERROR;
@@ -159,11 +169,15 @@ int sc_main(int argc, char *argv[]) {
159 169
     ///////////////////////////////////////////////////////////////////////////
160 170
     // run simulation
161 171
     ///////////////////////////////////////////////////////////////////////////
162
-    if(vm.count("max_time")){
163
-    	sc_core::sc_time max_time = scc::parse_from_string(vm["max_time"].as<std::string>());
164
-    	sc_core::sc_start(max_time);
165
-    } else
166
-    	sc_core::sc_start();
172
+    try {
173
+        if(vm.count("max_time")){
174
+            sc_core::sc_time max_time = scc::parse_from_string(vm["max_time"].as<std::string>());
175
+            sc_core::sc_start(max_time);
176
+        } else
177
+            sc_core::sc_start();
178
+    } catch(sc_core::sc_report& rep){
179
+        CLOG(FATAL, SystemC)<<"IWEF"[rep.get_severity()]<<"("<<rep.get_id()<<") "<<rep.get_msg_type()<<": "<<rep.get_msg()<<std::endl;
180
+    }
167 181
     if (!sc_core::sc_end_of_simulation_invoked()) sc_core::sc_stop();
168 182
     return 0;
169 183
 }

+ 17
- 5
riscv.sc/src/sysc/aon.cpp View File

@@ -45,14 +45,19 @@ aon::aon(sc_core::sc_module_name nm)
45 45
 : sc_core::sc_module(nm)
46 46
 , tlm_target<>(clk)
47 47
 , NAMED(clk_i)
48
-, NAMED(rst_i)
48
+, NAMED(erst_n_i)
49
+, NAMED(lfclkc_o)
50
+, NAMED(rst_o)
49 51
 , NAMEDD(aon_regs, regs) {
50 52
     regs->registerResources(*this);
51 53
     SC_METHOD(clock_cb);
52 54
     sensitive << clk_i;
53 55
     SC_METHOD(reset_cb);
54
-    sensitive << rst_i;
55
-    dont_initialize();
56
+    sensitive << erst_n_i;
57
+}
58
+
59
+void aon::start_of_simulation() {
60
+    rst_o=true;
56 61
 }
57 62
 
58 63
 void aon::clock_cb() {
@@ -62,10 +67,17 @@ void aon::clock_cb() {
62 67
 aon::~aon() {}
63 68
 
64 69
 void aon::reset_cb() {
65
-    if (rst_i.read())
70
+    if (!erst_n_i.read()){
66 71
         regs->reset_start();
67
-    else
72
+        rst_o=true;
73
+    } else {
68 74
         regs->reset_stop();
75
+        rst_o=false;
76
+    }
77
+    lfclkc_o.write(sc_core::sc_time(1/32768., sc_core::SC_SEC));
78
+}
79
+
80
+void aon::reset_internal_cb() {
69 81
 }
70 82
 
71 83
 } /* namespace sysc */

+ 27
- 7
riscv.sc/src/sysc/core_complex.cpp View File

@@ -101,6 +101,12 @@ public:
101 101
 
102 102
     uint32_t get_mode(){ return this->reg.machine_state; }
103 103
 
104
+    inline
105
+    void set_interrupt_execution(bool v){ this->interrupt_sim=v;}
106
+
107
+    inline
108
+    bool get_interrupt_execution(){ return this->interrupt_sim;}
109
+
104 110
     base_type::hart_state<base_type::reg_t>& get_state() { return this->state; }
105 111
 
106 112
     void notify_phase(exec_phase p) override {
@@ -241,6 +247,8 @@ core_complex::core_complex(sc_core::sc_module_name name)
241 247
     SC_THREAD(run);
242 248
     SC_METHOD(clk_cb);
243 249
     sensitive << clk_i;
250
+    SC_METHOD(rst_cb);
251
+    sensitive << rst_i;
244 252
     SC_METHOD(sw_irq_cb);
245 253
     sensitive<<sw_irq_i;
246 254
     SC_METHOD(timer_irq_cb);
@@ -299,6 +307,12 @@ void core_complex::disass_output(uint64_t pc, const std::string instr_str) {
299 307
 
300 308
 void core_complex::clk_cb() {
301 309
 	curr_clk = clk_i.read();
310
+	if(curr_clk==SC_ZERO_TIME) cpu->set_interrupt_execution(true);
311
+}
312
+
313
+void core_complex::rst_cb() {
314
+    if(rst_i.read())
315
+        cpu->set_interrupt_execution(true);
302 316
 }
303 317
 
304 318
 void core_complex::sw_irq_cb(){
@@ -314,13 +328,19 @@ void core_complex::global_irq_cb(){
314 328
 }
315 329
 
316 330
 void core_complex::run() {
317
-    wait(sc_core::SC_ZERO_TIME);
318
-    cpu->reset(reset_address.get_value());
319
-    try {
320
-        vm->start(-1);
321
-    } catch (simulation_stopped &e) {
322
-    }
323
-    sc_core::sc_stop();
331
+    wait(SC_ZERO_TIME); // separate from elaboration phase
332
+    do{
333
+        if(rst_i.read()){
334
+            cpu->reset(reset_address.get_value());
335
+            wait(rst_i.negedge_event());
336
+        }
337
+        while(clk_i.read()==SC_ZERO_TIME){
338
+            wait(clk_i.value_changed_event());
339
+        }
340
+        cpu->set_interrupt_execution(false);
341
+        vm->start();
342
+    } while(cpu->get_interrupt_execution());
343
+    sc_stop();
324 344
 }
325 345
 
326 346
 bool core_complex::read_mem(uint64_t addr, unsigned length, uint8_t *const data, bool is_fetch) {

+ 47
- 7
riscv.sc/src/sysc/gpio.cpp View File

@@ -73,6 +73,7 @@ gpio::gpio(sc_core::sc_module_name nm)
73 73
     }
74 74
     auto iof0_i_cb =[this](unsigned int tag, tlm::tlm_signal_gp<bool>& gp,
75 75
             tlm::tlm_phase& phase, sc_core::sc_time& delay)->tlm::tlm_sync_enum{
76
+        last_iof0[tag]=gp.get_value();
76 77
         this->iof_input(tag, 0, gp, delay);
77 78
         return tlm::TLM_COMPLETED;
78 79
     };
@@ -83,6 +84,7 @@ gpio::gpio(sc_core::sc_module_name nm)
83 84
     }
84 85
     auto iof1_i_cb =[this](unsigned int tag, tlm::tlm_signal_gp<bool>& gp,
85 86
             tlm::tlm_phase& phase, sc_core::sc_time& delay)->tlm::tlm_sync_enum{
87
+        last_iof1[tag]=gp.get_value();
86 88
         this->iof_input(tag, 1, gp, delay);
87 89
         return tlm::TLM_COMPLETED;
88 90
     };
@@ -99,6 +101,13 @@ gpio::gpio(sc_core::sc_module_name nm)
99 101
         }
100 102
         return true;
101 103
     });
104
+    regs->iof_en.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool {
105
+        if (!this->regs->in_reset()) {
106
+            enable_outputs(data);
107
+            reg.put(data);
108
+        }
109
+        return true;
110
+    });
102 111
 
103 112
 }
104 113
 
@@ -123,21 +132,51 @@ void gpio::clock_cb() {
123 132
 	this->clk = clk_i.read();
124 133
 }
125 134
 
135
+tlm::tlm_phase gpio::write_output(tlm::tlm_signal_gp<sc_dt::sc_logic>& gp, size_t i, sc_dt::sc_logic val) {
136
+    sc_core::sc_time delay{SC_ZERO_TIME};
137
+    tlm::tlm_phase phase{ tlm::BEGIN_REQ };
138
+    gp.set_command(tlm::TLM_WRITE_COMMAND);
139
+    gp.set_response_status(tlm::TLM_OK_RESPONSE);
140
+    gp.set_value(val);
141
+    pins_o.at(i)->nb_transport_fw(gp, phase, delay);
142
+    return phase;
143
+}
144
+
126 145
 void gpio::update_pins() {
127 146
 	sc_core::sc_inout_rv<32>::data_type out_val;
128 147
 	tlm::tlm_signal_gp<sc_dt::sc_logic> gp;
129 148
 	for(size_t i=0, mask = 1; i<32; ++i, mask<<=1){
130 149
 	    if((regs->iof_en&mask == 0) || (iof0_i[i].size()==0 && iof1_i[i].size()==0)){
131
-	        sc_core::sc_time delay{SC_ZERO_TIME};
132
-            tlm::tlm_phase phase{tlm::BEGIN_REQ};
133
-            gp.set_command(tlm::TLM_WRITE_COMMAND);
134
-            gp.set_response_status(tlm::TLM_OK_RESPONSE);
135
-            gp.set_value(regs->r_output_en&mask?regs->r_port&mask?sc_dt::Log_1:sc_dt::Log_0:sc_dt::Log_Z);
136
-            pins_o.at(i)->nb_transport_fw(gp, phase, delay);
150
+	        auto val = regs->r_output_en&mask?
151
+	                regs->r_port&mask?
152
+	                        sc_dt::Log_1:
153
+	                        sc_dt::Log_0:
154
+	                sc_dt::Log_Z;
155
+            tlm::tlm_phase phase = write_output(gp, i, val);
137 156
 	    }
138 157
 	}
139 158
 }
140 159
 
160
+void gpio::enable_outputs(uint32_t new_data) {
161
+    auto changed_bits = regs->r_iof_en^new_data;
162
+    tlm::tlm_signal_gp<sc_dt::sc_logic> gp;
163
+    for(size_t i=0, mask=1; i<32; ++i, mask<<=1){
164
+        if(changed_bits&mask){
165
+            if(new_data&mask){
166
+                if((regs->r_iof_sel&mask)==0 && iof0_i[i].size()>0){
167
+                    tlm::tlm_phase phase = write_output(gp, i, last_iof0[i]?sc_dt::Log_1:sc_dt::Log_0);
168
+                } else if((regs->r_iof_sel&mask)==1 && iof1_i[i].size()>0)
169
+                    tlm::tlm_phase phase = write_output(gp, i, last_iof1[i]?sc_dt::Log_1:sc_dt::Log_0);
170
+            } else {
171
+                auto val = regs->r_output_en&mask?
172
+                        regs->r_port&mask?sc_dt::Log_1:sc_dt::Log_0:
173
+                        sc_dt::Log_Z;
174
+                tlm::tlm_phase phase = write_output(gp, i, val);
175
+            }
176
+        }
177
+    }
178
+}
179
+
141 180
 void gpio::pin_input(unsigned int tag, tlm::tlm_signal_gp<sc_logic>& gp, sc_core::sc_time& delay) {
142 181
     if(delay>SC_ZERO_TIME){
143 182
          wait(delay);
@@ -187,7 +226,8 @@ void gpio::iof_input(unsigned int tag, unsigned iof_idx, tlm::tlm_signal_gp<>& g
187 226
                 tlm::tlm_phase phase{tlm::BEGIN_REQ};
188 227
                 tlm::tlm_signal_gp<sc_logic> new_gp;
189 228
                 new_gp.set_command(tlm::TLM_WRITE_COMMAND);
190
-                new_gp.set_value(gp.get_value()?sc_dt::Log_1:sc_dt::Log_0);
229
+                auto val = gp.get_value();
230
+                new_gp.set_value(val?sc_dt::Log_1:sc_dt::Log_0);
191 231
                 new_gp.copy_extensions_from(gp);
192 232
                 socket->nb_transport_fw(new_gp, phase, delay); // we don't care about phase and sync enum
193 233
             }

+ 6
- 12
riscv.sc/src/sysc/platform.cpp View File

@@ -42,6 +42,7 @@ platform::platform(sc_core::sc_module_name nm)
42 42
 : sc_core::sc_module(nm)
43 43
 , NAMED(pins_o, 32)
44 44
 , NAMED(pins_i, 32)
45
+, NAMED(erst_n)
45 46
 , NAMED(i_core_complex)
46 47
 , NAMED(i_router, 12, 1)
47 48
 , NAMED(i_uart0)
@@ -85,7 +86,8 @@ platform::platform(sc_core::sc_module_name nm)
85 86
     i_gpio0.clk_i(s_tlclk);
86 87
     i_plic.clk_i(s_tlclk);
87 88
     i_aon.clk_i(s_tlclk);
88
-    i_prci.clk_i(s_tlclk);
89
+    i_aon.lfclkc_o(s_lfclk);
90
+    i_prci.hfclk_o(s_tlclk); // clock driver
89 91
     i_clint.tlclk_i(s_tlclk);
90 92
     i_clint.lfclk_i(s_lfclk);
91 93
     i_core_complex.clk_i(s_tlclk);
@@ -97,11 +99,13 @@ platform::platform(sc_core::sc_module_name nm)
97 99
     i_qspi2.rst_i(s_rst);
98 100
     i_gpio0.rst_i(s_rst);
99 101
     i_plic.rst_i(s_rst);
100
-    i_aon.rst_i(s_rst);
102
+    i_aon.rst_o(s_rst);
101 103
     i_prci.rst_i(s_rst);
102 104
     i_clint.rst_i(s_rst);
103 105
     i_core_complex.rst_i(s_rst);
104 106
 
107
+    i_aon.erst_n_i(erst_n);
108
+
105 109
     i_clint.mtime_int_o(s_mtime_int);
106 110
     i_clint.msip_int_o(s_msie_int);
107 111
 
@@ -124,17 +128,7 @@ platform::platform(sc_core::sc_module_name nm)
124 128
     i_uart1.rx_i(s_dummy_sck_o[0]);
125 129
     i_uart1.irq_o(s_dummy[0]);
126 130
 
127
-    SC_THREAD(gen_reset);
128
-
129 131
     for(auto& sock:s_dummy_sck_i) sock.error_if_no_callback=false;
130 132
 }
131 133
 
132
-void platform::gen_reset() {
133
-    s_tlclk = 10_ns;
134
-    s_lfclk = 30517_ns;
135
-    s_rst = true;
136
-    wait(10_ns);
137
-    s_rst = false;
138
-}
139
-
140 134
 } /* namespace sysc */

+ 62
- 12
riscv.sc/src/sysc/prci.cpp View File

@@ -43,24 +43,35 @@ namespace sysc {
43 43
 
44 44
 prci::prci(sc_core::sc_module_name nm)
45 45
 : sc_core::sc_module(nm)
46
-, tlm_target<>(clk)
47
-, NAMED(clk_i)
46
+, tlm_target<>(hfclk)
48 47
 , NAMED(rst_i)
48
+, NAMED(hfclk_o)
49 49
 , NAMEDD(prci_regs, regs) {
50 50
     regs->registerResources(*this);
51
-    SC_METHOD(clock_cb);
52
-    sensitive << clk_i;
53 51
     SC_METHOD(reset_cb);
54 52
     sensitive << rst_i;
55 53
     dont_initialize();
54
+    SC_METHOD(hfxosc_cb);
55
+    sensitive << hfxosc_i;
56 56
     SC_METHOD(hfrosc_en_cb);
57 57
     sensitive << hfrosc_en_evt;
58 58
     dont_initialize();
59 59
 
60
+    regs->hfxosccfg.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool {
61
+        reg.put(data);
62
+        if (this->regs->r_hfxosccfg.hfxoscen==1) { // check rosc_en
63
+            this->hfxosc_en_evt.notify(1, sc_core::SC_US);
64
+        } else {
65
+            this->hfxosc_en_evt.notify(SC_ZERO_TIME);
66
+        }
67
+        return true;
68
+    });
60 69
     regs->hfrosccfg.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool {
61 70
         reg.put(data);
62
-        if (this->regs->r_hfrosccfg & (1 << 30)) { // check rosc_en
71
+        if (this->regs->r_hfrosccfg.hfroscen==1) { // check rosc_en
63 72
             this->hfrosc_en_evt.notify(1, sc_core::SC_US);
73
+        } else {
74
+            this->hfrosc_en_evt.notify(SC_ZERO_TIME);
64 75
         }
65 76
         return true;
66 77
     });
@@ -70,13 +81,15 @@ prci::prci(sc_core::sc_module_name nm)
70 81
         if (pllcfg.pllbypass == 0 && pllcfg.pllq != 0) { // set pll_lock if pll is selected
71 82
             pllcfg.plllock = 1;
72 83
         }
84
+        update_hfclk();
73 85
         return true;
74 86
     });
75
-}
76
-
77
-void prci::clock_cb() {
78
-	this->clk = clk_i.read();
79
-
87
+    regs->plloutdiv.set_write_cb([this](scc::sc_register<uint32_t> &reg, uint32_t data) -> bool {
88
+        reg.put(data);
89
+        update_hfclk();
90
+        return true;
91
+    });
92
+    hfxosc_clk=62.5_ns;
80 93
 }
81 94
 
82 95
 prci::~prci() {}
@@ -84,12 +97,49 @@ prci::~prci() {}
84 97
 void prci::reset_cb() {
85 98
     if (rst_i.read())
86 99
         regs->reset_start();
87
-    else
100
+    else {
88 101
         regs->reset_stop();
102
+        this->hfxosc_en_evt.notify(1, sc_core::SC_US);
103
+    }
104
+}
105
+
106
+void prci::hfxosc_cb() {
107
+    this->regs->r_hfxosccfg.hfxoscrdy=0;
108
+    this->hfxosc_en_evt.notify(1, sc_core::SC_US);
109
+
110
+}
111
+
112
+void prci::hfxosc_en_cb() {
113
+    update_hfclk();
114
+    if(regs->r_hfxosccfg.hfxoscen==1)// set rosc_rdy
115
+        regs->r_hfxosccfg.hfxoscrdy =1;
116
+    else
117
+        regs->r_hfxosccfg.hfxoscrdy =0;
89 118
 }
90 119
 
91 120
 void prci::hfrosc_en_cb() {
92
-    regs->r_hfrosccfg |= (1 << 31); // set rosc_rdy
121
+    update_hfclk();
122
+    auto& hfrosccfg=regs->r_hfrosccfg;
123
+    if(regs->r_hfrosccfg.hfroscen==1) {// set rosc_rdy
124
+        regs->r_hfrosccfg.hfroscrdy =1;
125
+    } else {
126
+        regs->r_hfrosccfg.hfroscrdy =0;
127
+    }
128
+}
129
+
130
+void prci::update_hfclk() {
131
+    auto& hfrosccfg=regs->r_hfrosccfg;
132
+    auto& pllcfg=regs->r_pllcfg;
133
+    auto& plldiv=regs->r_plloutdiv;
134
+    hfrosc_clk = sc_core::sc_time(((hfrosccfg.hfroscdiv+1)*1.0)/(1125000.0*(hfrosccfg.hfrosctrim+1)), sc_core::SC_SEC);
135
+    auto pll_ref = pllcfg.pllrefsel==1?hfxosc_clk:hfrosc_clk;
136
+    auto r = pllcfg.pllr+1;
137
+    auto f = 2*(pllcfg.pllf+1);
138
+    auto q = 1<<pllcfg.pllq;
139
+    auto pll_out = pllcfg.pllbypass==1 || pllcfg.plllock==0?pll_ref:((pll_ref*r)/f)*q;
140
+    auto pll_res = plldiv&0x100?pll_out:2*pll_out*((plldiv&0x3f)+1);
141
+    hfclk = pllcfg.pllsel?pll_res:hfrosc_clk;
142
+    hfclk_o.write(hfclk);
93 143
 }
94 144
 
95 145
 } /* namespace sysc */

+ 16
- 6
riscv.sc/src/sysc/system.cpp View File

@@ -12,19 +12,29 @@ using namespace sysc;
12 12
 system::system(sc_core::sc_module_name nm)
13 13
 : sc_module(nm)
14 14
 , NAMED(s_gpio, 32)
15
+, NAMED(s_rst_n)
15 16
 , NAMED(i_platform)
16 17
 , NAMED(i_terminal)
17 18
 {
18
-  for(auto i=0U; i<s_gpio.size(); ++i){
19
+    // connect platform
20
+    i_platform.erst_n(s_rst_n);
21
+
22
+    for(auto i=0U; i<s_gpio.size(); ++i){
19 23
       s_gpio[i].in(i_platform.pins_o[i]);
20 24
       i_platform.pins_i[i](s_gpio[i].out);
21
-  }
22
-//  i_platform.pins_i(i_platform.pins_o);
23
-
24
-  s_gpio[17].out(i_terminal.rx_i);
25
-  i_terminal.tx_o(s_gpio[16].in);
25
+    }
26
+    // connect other units
27
+    s_gpio[17].out(i_terminal.rx_i);
28
+    i_terminal.tx_o(s_gpio[16].in);
29
+    SC_THREAD(gen_por);
26 30
 }
27 31
 
28 32
 system::~system() {
29 33
 }
30 34
 
35
+void sysc::system::gen_por() {
36
+    // single shot
37
+    s_rst_n = false;
38
+    wait(10_ns);
39
+    s_rst_n = true;
40
+}

+ 23
- 37
riscv.sc/src/sysc/uart.cpp View File

@@ -134,54 +134,40 @@ void uart::reset_cb() {
134 134
 
135 135
 void uart::transmit_data() {
136 136
     uint8_t txdata;
137
-    sc_core::sc_time delay(SC_ZERO_TIME);
137
+    sysc::tlm_signal_uart_extension ext;
138 138
     tlm::tlm_phase phase(tlm::BEGIN_REQ);
139 139
     tlm::tlm_signal_gp<> gp;
140
-    gp.set_command(tlm::TLM_WRITE_COMMAND);
141
-    gp.set_value(true);
142
-    tx_o->nb_transport_fw(gp, phase, delay);
140
+    sc_core::sc_time delay(SC_ZERO_TIME);
141
+    sc_core::sc_time bit_duration(SC_ZERO_TIME);
142
+
143
+    gp.set_extension(&ext);
144
+    ext.tx.data_bits=8;
145
+    ext.tx.parity=false;
146
+
147
+    auto set_bit = [&](bool val){
148
+        gp.set_command(tlm::TLM_WRITE_COMMAND);
149
+        gp.set_value(val);
150
+        tlm::tlm_phase phase(tlm::BEGIN_REQ);
151
+        tx_o->nb_transport_fw(gp, phase, delay);
152
+        if(delay<bit_duration) wait(bit_duration-delay);
153
+    };
154
+    wait(delay);
143 155
     while(true){
156
+        set_bit(true);
144 157
         wait(tx_fifo.data_written_event());
145 158
         while(tx_fifo.nb_read(txdata)){
146 159
             regs->r_txdata.full=tx_fifo.num_free()==0;
147 160
             regs->r_ip.txwm=regs->r_txctrl.txcnt<=(7-tx_fifo.num_free())?1:0;
148
-            auto bit_duration = (regs->r_div.div+1)*clk;
149
-            sysc::tlm_signal_uart_extension ext;
161
+            bit_duration = (regs->r_div.div+1)*clk;
150 162
             ext.start_time = sc_core::sc_time_stamp();
151
-            ext.tx.data_bits=8;
152
-            ext.tx.parity=false;
153 163
             ext.tx.stop_bits=1+regs->r_txctrl.nstop;
154 164
             ext.tx.baud_rate=static_cast<unsigned>(1/bit_duration.to_seconds());
155 165
             ext.tx.data=txdata;
156
-            delay=SC_ZERO_TIME;
157
-            auto start = sc_time_stamp();
158
-            gp.set_command(tlm::TLM_WRITE_COMMAND);
159
-            gp.set_value(false);
160
-            gp.set_extension(&ext);
161
-            phase=tlm::BEGIN_REQ;
162
-            tx_o->nb_transport_fw(gp, phase, delay);
163
-            auto duration = bit_duration*(1+8+1+ext.tx.stop_bits);//start+data+parity+stop
164
-            auto diff=start+duration-sc_time_stamp();
165
-            if(diff>SC_ZERO_TIME) wait(diff);
166
-            delay=SC_ZERO_TIME;
167
-            gp.set_command(tlm::TLM_WRITE_COMMAND);
168
-            gp.set_value(true);
169
-            phase=tlm::BEGIN_REQ;
170
-            tx_o->nb_transport_fw(gp, phase, delay);
171
-
172
-//            if(txdata != '\r') queue.push_back(txdata);
173
-//            if (queue.size() >> 0 && (txdata == '\n' || txdata == 0)) {
174
-//                std::string msg(queue.begin(), queue.end()-1);
175
-//                LOG(INFO) << this->name() << " transmit: '" << msg << "'";
176
-//                sc_core::sc_time now = sc_core::sc_time_stamp();
177
-//                if(handler)
178
-//                    sc_comm_singleton::inst().execute([this, msg, now](){
179
-//                        std::stringstream os;
180
-//                        os << "{\"time\":\"" << now << "\",\"message\":\""<<msg<<"\"}";
181
-//                        this->handler->send(os.str());
182
-//                    });
183
-//                queue.clear();
184
-//            }
166
+            set_bit(false); // start bit
167
+            for(int i = 8; i>0; --i)
168
+                set_bit(txdata&(1<<(i-1))); // 8 data bits, MSB first
169
+            set_bit(true); // stop bit 1
170
+            if(regs->r_txctrl.nstop) set_bit(true); // stop bit 2
185 171
         }
186 172
     }
187 173
 }

+ 1
- 0
riscv/gen_input/templates/incl-CORENAME.h.gtl View File

@@ -162,6 +162,7 @@ protected:
162 162
 
163 163
     std::array<address_type, 4> addr_mode;
164 164
     
165
+    bool interrupt_sim=false;
165 166
 <%
166 167
 def fcsr = allRegs.find {it.name=='FCSR'}
167 168
 if(fcsr != null) {%>

+ 6
- 6
riscv/gen_input/templates/src-CORENAME.cpp.gtl View File

@@ -1,21 +1,21 @@
1 1
 ////////////////////////////////////////////////////////////////////////////////
2
-// Copyright (C) 2017, MINRES Technologies GmbH
2
+// Copyright (C) 2017,2018 MINRES Technologies GmbH
3 3
 // All rights reserved.
4
-// 
4
+//
5 5
 // Redistribution and use in source and binary forms, with or without
6 6
 // modification, are permitted provided that the following conditions are met:
7
-// 
7
+//
8 8
 // 1. Redistributions of source code must retain the above copyright notice,
9 9
 //    this list of conditions and the following disclaimer.
10
-// 
10
+//
11 11
 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 12
 //    this list of conditions and the following disclaimer in the documentation
13 13
 //    and/or other materials provided with the distribution.
14
-// 
14
+//
15 15
 // 3. Neither the name of the copyright holder nor the names of its contributors
16 16
 //    may be used to endorse or promote products derived from this software
17 17
 //    without specific prior written permission.
18
-// 
18
+//
19 19
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 20
 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 21
 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

+ 2
- 0
riscv/incl/iss/arch/rv32gc.h View File

@@ -179,6 +179,8 @@ struct rv32gc: public arch_if {
179 179
 
180 180
     uint64_t get_icount() { return reg.icount;}
181 181
 
182
+    bool should_stop(){return false;}
183
+
182 184
     inline phys_addr_t v2p(const iss::addr_t& addr){
183 185
         if(addr.space != traits<rv32gc>::MEM ||
184 186
                 addr.type == iss::address_type::PHYSICAL ||

+ 5
- 0
riscv/incl/iss/arch/rv32imac.h View File

@@ -144,8 +144,12 @@ struct rv32imac: public arch_if {
144 144
     /// deprecated
145 145
     void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {};
146 146
 
147
+    inline
147 148
     uint64_t get_icount() { return reg.icount;}
148 149
 
150
+    inline
151
+    bool should_stop() { return interrupt_sim;}
152
+
149 153
     inline phys_addr_t v2p(const iss::addr_t& addr){
150 154
         if(addr.space != traits<rv32imac>::MEM ||
151 155
                 addr.type == iss::address_type::PHYSICAL ||
@@ -204,6 +208,7 @@ protected:
204 208
 
205 209
     std::array<address_type, 4> addr_mode;
206 210
     
211
+    bool interrupt_sim=false;
207 212
 
208 213
 	uint32_t get_fcsr(){return 0;}
209 214
 	void set_fcsr(uint32_t val){}

+ 2
- 0
riscv/incl/iss/arch/rv64ia.h View File

@@ -146,6 +146,8 @@ struct rv64ia: public arch_if {
146 146
 
147 147
     uint64_t get_icount() { return reg.icount;}
148 148
 
149
+    bool should_stop(){return false;}
150
+
149 151
     inline phys_addr_t v2p(const iss::addr_t& addr){
150 152
         if(addr.space != traits<rv64ia>::MEM ||
151 153
                 addr.type == iss::address_type::PHYSICAL ||

+ 1
- 0
riscv/src/iss/rv32gc.cpp View File

@@ -62,6 +62,7 @@ void rv32gc::reset(uint64_t address) {
62 62
     reg.NEXT_PC=reg.PC;
63 63
     reg.trap_state=0;
64 64
     reg.machine_state=0x0;
65
+    reg.icount=0;
65 66
 }
66 67
 
67 68
 uint8_t* rv32gc::get_regs_base_ptr(){

+ 1
- 0
riscv/src/iss/rv64ia.cpp View File

@@ -63,6 +63,7 @@ void rv64ia::reset(uint64_t address) {
63 63
     reg.NEXT_PC = reg.PC;
64 64
     reg.trap_state = 0;
65 65
     reg.machine_state = 0x3;
66
+    reg.icount=0;
66 67
 }
67 68
 
68 69
 uint8_t *rv64ia::get_regs_base_ptr() { return reinterpret_cast<uint8_t *>(&reg); }

+ 1
- 1
sc-components

@@ -1 +1 @@
1
-Subproject commit 019a04132a8beb7fcab24d504e3347ca0771ea5f
1
+Subproject commit 57853f5df2ee573c35ef598a8a259696ae6059c0