added sc_comm_singleton to coordinate interaction with clients (e.g. web
browser)
This commit is contained in:
		| @@ -6,6 +6,7 @@ SystemCVerification/2.0.0a@minres/stable | ||||
|  | ||||
| [generators] | ||||
| cmake | ||||
| txt | ||||
|  | ||||
| [options] | ||||
| Poco:shared=True | ||||
|   | ||||
							
								
								
									
										33
									
								
								html/app.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								html/app.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| var ws; | ||||
|  | ||||
| $(function() { | ||||
|     ws = new WebSocket('ws://' + document.location.host + '/ws'); | ||||
|     ws.onopen = function() { | ||||
|         console.log('onopen'); | ||||
|     }; | ||||
|     ws.onclose = function() { | ||||
|         $('#message').text('Lost connection.'); | ||||
|         console.log('onclose'); | ||||
|     }; | ||||
|     ws.onmessage = function(message) { | ||||
|         console.log("got '" + message.data + "'"); | ||||
|         eval(message.data); | ||||
|     }; | ||||
|     ws.onerror = function(error) { | ||||
|         console.log('onerror ' + error); | ||||
|         console.log(error); | ||||
|     }; | ||||
|     $('#count').click(function() { | ||||
|     	ws.send($('#count').val()); | ||||
|     }); | ||||
|     $('#close').click(function() { | ||||
|       ws.send('close'); | ||||
|     }); | ||||
|     $('#die').click(function() { | ||||
|       ws.send('die'); | ||||
|     }); | ||||
| }); | ||||
|  | ||||
| set = function(value) { | ||||
| 	$('#count').val(value) | ||||
| } | ||||
							
								
								
									
										14
									
								
								html/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								html/index.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|   <head> | ||||
|     <title>Hello, world</title> | ||||
|     <script src='lib/jquery.min.js'></script> | ||||
|     <script src='app.js'></script> | ||||
|   </head> | ||||
|   <body> | ||||
| 	<input id="count" type="button" value="..."></input> | ||||
| 	<input id="close" type="button" value="Close"></input> | ||||
| 	<input id="die" type="button" value="Die"></input> | ||||
|   </body> | ||||
| </html> | ||||
|  | ||||
							
								
								
									
										16
									
								
								html/lib/jquery.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								html/lib/jquery.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										105
									
								
								html/ws.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								html/ws.html
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| <!doctype html> | ||||
| <html lang=en> | ||||
| 	<head> | ||||
| 		<meta charset=utf-8> | ||||
| 		<meta name=viewport content="width=device-width, initial-scale=1"> | ||||
| 		<title>system output</title> | ||||
| <style> | ||||
| h1 { font-family: helvetica, sans-serif; margin: 0; } | ||||
| h1+p { margin: 0; } | ||||
| li { font-family: Courier; list-style-type: '>';} | ||||
| pre { margin-top:0; margin-bottom:0;} | ||||
| .term { background-color:black; color:white; font-weight:bold;padding-top:10px; padding-bottom:10px; max-height:400px; overflow: scroll;} | ||||
| span.timestamp { font-family: monospace; white-space: pre;width: 50px;} | ||||
| span.value_1 { background-color: green;} | ||||
| span.value_0 { background-color: blue;} | ||||
| span.value_x { background-color: red;} | ||||
| </style> | ||||
| 	</head> | ||||
| 	<body> | ||||
| 		<h1>system output</h1> | ||||
| 		<div id="top"> | ||||
| 		</div> | ||||
| 		<script> | ||||
| 		String.format = function() { | ||||
| 		    // The string containing the format items (e.g. "{0}") | ||||
| 		    // will and always has to be the first argument. | ||||
| 		    var theString = arguments[0]; | ||||
| 		    // start with the second argument (i = 1) | ||||
| 		    for (var i = 1; i < arguments.length; i++) { | ||||
| 		        // "gm" = RegEx options for Global search (more than one instance) | ||||
| 		        // and for Multiline search | ||||
| 		        var regEx = new RegExp("\\{" + (i - 1) + "\\}", "gm"); | ||||
| 		        theString = theString.replace(regEx, arguments[i]); | ||||
| 		    } | ||||
| 		     | ||||
| 		    return theString; | ||||
| 		} | ||||
| 		String.prototype.paddingLeft = function (paddingValue) { | ||||
| 			return String(paddingValue + this).slice(-paddingValue.length); | ||||
| 		}; | ||||
| 		var log = function (n, m) { | ||||
| 			console.log(m); | ||||
| 	        var data = JSON.parse(m); | ||||
| 	        if( data.hasOwnProperty("message") ) { | ||||
| 				var ul = document.getElementById(n); | ||||
| 			    var li = document.createElement('li'); | ||||
| 			    var p = document.createElement('pre'); | ||||
| 		        // i.innerText = new Date().toISOString()+': '+m; | ||||
| 		        p.innerText = '['+data.time.paddingLeft('                    ')+'] '+ data.message; | ||||
| 		        li.appendChild(p); | ||||
| 			    ul.appendChild(li); | ||||
| 			    var objDiv = document.getElementById(n + '_container'); | ||||
| 			    objDiv.scrollTop = objDiv.scrollHeight; | ||||
| 			} else if(data.hasOwnProperty("data")){ | ||||
| 				var ul = document.getElementById(n); | ||||
| 			    var li = document.createElement('li'); | ||||
| 			    var span = document.createElement('span'); | ||||
| 			    span.className="timestamp"; | ||||
| 			    span.innerText='['+data.time.paddingLeft('                    ')+']' | ||||
| 			    li.appendChild(span); | ||||
| 			    var s = data.data; | ||||
| 			    for ( var i = 0; i < s.length; i++ ){ | ||||
| 				    var spani = document.createElement('span'); | ||||
| 				    if(s.charAt(i) == 'Z') | ||||
| 				    	spani.className="value_z"; | ||||
| 				    else if(s.charAt(i) == '1') | ||||
| 				    	spani.className="value_1"; | ||||
| 				    else if(s.charAt(i) == '0') | ||||
| 				    	spani.className="value_0"; | ||||
| 				    else if(s.charAt(i) == 'X') | ||||
| 				    	spani.className="value_x"; | ||||
| 				    spani.appendChild(document.createTextNode('\u00A0')); | ||||
| 				    li.appendChild(spani);			    	 | ||||
| 			    } | ||||
| 			    ul.appendChild(li); | ||||
| 			    var objDiv = document.getElementById(n + '_container'); | ||||
| 			    objDiv.scrollTop = objDiv.scrollHeight; | ||||
| 			} | ||||
| 		} | ||||
| 		var open_connection = function(name){ | ||||
| 			var s = new WebSocket('ws://'+window.location.host+'/ws/i_simple_system.i_'+name); | ||||
| 			s.addEventListener('error',   function (m) { log(name, new Date().toISOString()+': ===connection error ==='); }); | ||||
| 			s.addEventListener('open',    function (m) { log(name, new Date().toISOString()+': ===connection opened==='); }); | ||||
| 			s.addEventListener('message', function (m) { log(name, m.data); }); | ||||
| 			s.addEventListener('close',   function (m) { log(name, new Date().toISOString()+': ===connection closed==='); }); | ||||
| 		} | ||||
| 		var createElem = function(n){ | ||||
| 			var top = document.getElementById('top'); | ||||
| 			var p = document.createElement('p'); | ||||
| 			p.innerText="Component " + n; | ||||
| 			var div = document.createElement('div'); | ||||
| 			div.className = "term"; | ||||
| 			div.id= n + '_container'; | ||||
| 			var ul = document.createElement('ul'); | ||||
| 			ul.id= n; | ||||
| 			div.appendChild(ul); | ||||
| 			top.appendChild(p); | ||||
| 			top.appendChild(div); | ||||
| 			open_connection(n); | ||||
| 		} | ||||
| 		createElem("uart0"); | ||||
| 		createElem("gpio0"); | ||||
| 		</script> | ||||
| 	</body> | ||||
| </html> | ||||
| @@ -12,8 +12,13 @@ addrmap e300_plat_t { | ||||
|     plic_regs  plic  @0x0C000000; | ||||
|     aon_regs   aon   @0x10000000; | ||||
|     prci_regs  prci  @0x10008000; | ||||
|     gpio_regs  gpio  @0x10012000; | ||||
|     gpio_regs  gpio0 @0x10012000; | ||||
|     uart_regs  uart0 @0x10013000; | ||||
|     spi_regs   spi   @0x10014000;   | ||||
|     spi_regs   qspi0 @0x10014000;   | ||||
|     //pwm_regs pwm0  @0x10015000; | ||||
|     uart_regs  uart1 @0x10023000; | ||||
|     spi_regs   qspi1 @0x10024000;   | ||||
|     //pwm_regs pwm1  @0x10025000; | ||||
|     spi_regs   qspi2 @0x10034000;   | ||||
|     //pwm_regs pwm2  @0x10035000; | ||||
| } e300_plat; | ||||
|   | ||||
| @@ -3,17 +3,17 @@ regfile plic_regs { | ||||
| 		name="priority"; | ||||
| 		desc="interrupt source priority"; | ||||
| 		field {} priority[2:0]; | ||||
| 	} priority[255] @0x004; | ||||
| 	} priority[256] @0x000; | ||||
| 	reg { | ||||
| 		name="pending"; | ||||
| 		desc="pending irq"; | ||||
| 		field {} pending[31:0]; | ||||
| 	} pending @0x1000; | ||||
| 	} pending[8] @0x1000; | ||||
| 	reg { | ||||
| 		name="enabled"; | ||||
| 		desc="enabled interrupts"; | ||||
| 		field {} enabled[31:0]; | ||||
| 	} enabled @0x2000; | ||||
| 	} enabled[8] @0x2000; | ||||
| 	reg { | ||||
| 		name="threshold"; | ||||
| 		desc="interrupt priority threshold"; | ||||
|   | ||||
| @@ -86,6 +86,14 @@ public: | ||||
|  | ||||
|     sc_core::sc_in<bool> rst_i; | ||||
|  | ||||
|     sc_core::sc_in<bool> global_irq_i; | ||||
|  | ||||
|     sc_core::sc_in<bool> timer_irq_i; | ||||
|  | ||||
|     sc_core::sc_in<bool> sw_irq_i; | ||||
|  | ||||
|     sc_core::sc_vector<sc_core::sc_in<bool>> local_irq_i; | ||||
|  | ||||
|     scc::ext_attribute<std::string> elf_file; | ||||
|  | ||||
|     scc::ext_attribute<bool> enable_disass; | ||||
| @@ -124,6 +132,9 @@ protected: | ||||
|     void start_of_simulation(); | ||||
|     void run(); | ||||
|     void clk_cb(); | ||||
|     void sw_irq_cb(); | ||||
|     void timer_irq_cb(); | ||||
|     void global_irq_cb(); | ||||
|     util::range_lut<tlm_dmi_ext> read_lut, write_lut; | ||||
|     tlm_utils::tlm_quantumkeeper quantum_keeper; | ||||
|     std::vector<uint8_t> write_buf; | ||||
|   | ||||
| @@ -28,7 +28,7 @@ | ||||
| // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
| // POSSIBILITY OF SUCH DAMAGE. | ||||
| // | ||||
| // Created on: Wed Oct 04 10:06:35 CEST 2017 | ||||
| // Created on: Fri Nov 10 18:01:53 CET 2017 | ||||
| //             *      aon_regs.h Author: <RDL Generator> | ||||
| // | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -36,66 +36,69 @@ | ||||
| #ifndef _AON_REGS_H_ | ||||
| #define _AON_REGS_H_ | ||||
|  | ||||
| #include <scc/utilities.h> | ||||
| #include <util/bit_field.h> | ||||
| #include "scc/register.h" | ||||
| #include "scc/tlm_target.h" | ||||
| #include "scc/utilities.h" | ||||
| #include <scc/register.h> | ||||
| #include <scc/tlm_target.h> | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| class aon_regs : public sc_core::sc_module, public scc::resetable { | ||||
| class aon_regs : | ||||
|         public sc_core::sc_module, | ||||
|         public scc::resetable | ||||
| { | ||||
| public: | ||||
|     // storage declarations | ||||
|     uint32_t r_wdogcfg; | ||||
|  | ||||
|      | ||||
|     uint32_t r_wdogcount; | ||||
|  | ||||
|      | ||||
|     uint32_t r_wdogs; | ||||
|  | ||||
|      | ||||
|     uint32_t r_wdogfeed; | ||||
|  | ||||
|      | ||||
|     uint32_t r_wdogkey; | ||||
|  | ||||
|      | ||||
|     uint32_t r_wdogcmp; | ||||
|  | ||||
|      | ||||
|     uint32_t r_rtccfg; | ||||
|  | ||||
|      | ||||
|     uint32_t r_rtclo; | ||||
|  | ||||
|      | ||||
|     uint32_t r_rtchi; | ||||
|  | ||||
|      | ||||
|     uint32_t r_rtcs; | ||||
|  | ||||
|      | ||||
|     uint32_t r_rtccmp; | ||||
|  | ||||
|      | ||||
|     uint32_t r_lfrosccfg; | ||||
|  | ||||
|      | ||||
|     std::array<uint32_t, 32> r_backup; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(pmuwakeupi_t, uint32_t); | ||||
|     BF_FIELD(delay, 0, 4); | ||||
|     BF_FIELD(vddpaden, 5, 1); | ||||
|     BF_FIELD(corerst, 7, 1); | ||||
|     BF_FIELD(hfclkrst, 8, 1); | ||||
|     END_BF_DECL(); | ||||
|         BF_FIELD(delay, 0, 4); | ||||
|         BF_FIELD(vddpaden, 5, 1); | ||||
|         BF_FIELD(corerst, 7, 1); | ||||
|         BF_FIELD(hfclkrst, 8, 1); | ||||
|     END_BF_DECL() ; | ||||
|     std::array<pmuwakeupi_t, 8> r_pmuwakeupi; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(pmusleepi_t, uint32_t); | ||||
|     BF_FIELD(delay, 0, 4); | ||||
|     BF_FIELD(vddpaden, 5, 1); | ||||
|     BF_FIELD(corerst, 7, 1); | ||||
|     BF_FIELD(hfclkrst, 8, 1); | ||||
|     END_BF_DECL(); | ||||
|         BF_FIELD(delay, 0, 4); | ||||
|         BF_FIELD(vddpaden, 5, 1); | ||||
|         BF_FIELD(corerst, 7, 1); | ||||
|         BF_FIELD(hfclkrst, 8, 1); | ||||
|     END_BF_DECL() ; | ||||
|     std::array<pmusleepi_t, 8> r_pmusleepi; | ||||
|  | ||||
|      | ||||
|     uint32_t r_pmuie; | ||||
|  | ||||
|      | ||||
|     uint32_t r_pmucause; | ||||
|  | ||||
|      | ||||
|     uint32_t r_pmusleep; | ||||
|  | ||||
|      | ||||
|     uint32_t r_pmukey; | ||||
|  | ||||
|      | ||||
|     // register declarations | ||||
|     scc::sc_register<uint32_t> wdogcfg; | ||||
|     scc::sc_register<uint32_t> wdogcount; | ||||
| @@ -116,10 +119,11 @@ public: | ||||
|     scc::sc_register<uint32_t> pmucause; | ||||
|     scc::sc_register<uint32_t> pmusleep; | ||||
|     scc::sc_register<uint32_t> pmukey; | ||||
|  | ||||
|      | ||||
|     aon_regs(sc_core::sc_module_name nm); | ||||
|  | ||||
|     template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target); | ||||
|     template<unsigned BUSWIDTH=32> | ||||
|     void registerResources(scc::tlm_target<BUSWIDTH>& target); | ||||
| }; | ||||
| } | ||||
| ////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -146,9 +150,12 @@ inline sysc::aon_regs::aon_regs(sc_core::sc_module_name nm) | ||||
| , NAMED(pmuie, r_pmuie, 0, *this) | ||||
| , NAMED(pmucause, r_pmucause, 0, *this) | ||||
| , NAMED(pmusleep, r_pmusleep, 0, *this) | ||||
| , NAMED(pmukey, r_pmukey, 0, *this) {} | ||||
| , NAMED(pmukey, r_pmukey, 0, *this) | ||||
| { | ||||
| } | ||||
|  | ||||
| template <unsigned BUSWIDTH> inline void sysc::aon_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) { | ||||
| template<unsigned BUSWIDTH> | ||||
| inline void sysc::aon_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) { | ||||
|     target.addResource(wdogcfg, 0x0UL); | ||||
|     target.addResource(wdogcount, 0x8UL); | ||||
|     target.addResource(wdogs, 0x10UL); | ||||
|   | ||||
| @@ -28,7 +28,7 @@ | ||||
| // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
| // POSSIBILITY OF SUCH DAMAGE. | ||||
| // | ||||
| // Created on: Wed Oct 04 10:06:35 CEST 2017 | ||||
| // Created on: Fri Nov 10 18:01:53 CET 2017 | ||||
| //             *      clint_regs.h Author: <RDL Generator> | ||||
| // | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -36,32 +36,36 @@ | ||||
| #ifndef _CLINT_REGS_H_ | ||||
| #define _CLINT_REGS_H_ | ||||
|  | ||||
| #include <scc/utilities.h> | ||||
| #include <util/bit_field.h> | ||||
| #include "scc/register.h" | ||||
| #include "scc/tlm_target.h" | ||||
| #include "scc/utilities.h" | ||||
| #include <scc/register.h> | ||||
| #include <scc/tlm_target.h> | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| class clint_regs : public sc_core::sc_module, public scc::resetable { | ||||
| class clint_regs : | ||||
|         public sc_core::sc_module, | ||||
|         public scc::resetable | ||||
| { | ||||
| public: | ||||
|     // storage declarations | ||||
|     BEGIN_BF_DECL(msip_t, uint32_t); | ||||
|     BF_FIELD(msip, 0, 1); | ||||
|         BF_FIELD(msip, 0, 1); | ||||
|     END_BF_DECL() r_msip; | ||||
|  | ||||
|      | ||||
|     uint64_t r_mtimecmp; | ||||
|  | ||||
|      | ||||
|     uint64_t r_mtime; | ||||
|  | ||||
|      | ||||
|     // register declarations | ||||
|     scc::sc_register<msip_t> msip; | ||||
|     scc::sc_register<uint64_t> mtimecmp; | ||||
|     scc::sc_register<uint64_t> mtime; | ||||
|  | ||||
|      | ||||
|     clint_regs(sc_core::sc_module_name nm); | ||||
|  | ||||
|     template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target); | ||||
|     template<unsigned BUSWIDTH=32> | ||||
|     void registerResources(scc::tlm_target<BUSWIDTH>& target); | ||||
| }; | ||||
| } | ||||
| ////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -72,9 +76,12 @@ inline sysc::clint_regs::clint_regs(sc_core::sc_module_name nm) | ||||
| : sc_core::sc_module(nm) | ||||
| , NAMED(msip, r_msip, 0, *this) | ||||
| , NAMED(mtimecmp, r_mtimecmp, 0, *this) | ||||
| , NAMED(mtime, r_mtime, 0, *this) {} | ||||
| , NAMED(mtime, r_mtime, 0, *this) | ||||
| { | ||||
| } | ||||
|  | ||||
| template <unsigned BUSWIDTH> inline void sysc::clint_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) { | ||||
| template<unsigned BUSWIDTH> | ||||
| inline void sysc::clint_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) { | ||||
|     target.addResource(msip, 0x0UL); | ||||
|     target.addResource(mtimecmp, 0x4000UL); | ||||
|     target.addResource(mtime, 0xbff8UL); | ||||
|   | ||||
| @@ -1,16 +1,17 @@ | ||||
| #ifndef _E300_PLAT_MAP_H_ | ||||
| #define _E300_PLAT_MAP_H_ | ||||
| // need double braces, see | ||||
| // https://stackoverflow.com/questions/6893700/how-to-construct-stdarray-object-with-initializer-list#6894191 | ||||
| const std::array<scc::target_memory_map_entry<32>, 8> e300_plat_map = {{ | ||||
| // need double braces, see https://stackoverflow.com/questions/6893700/how-to-construct-stdarray-object-with-initializer-list#6894191 | ||||
| const std::array<scc::target_memory_map_entry<32>, 10> e300_plat_map = {{ | ||||
|     {&i_clint, 0x2000000, 0xc000}, | ||||
|     {&i_plic, 0xc000000, 0x200008}, | ||||
|     {&i_aon, 0x10000000, 0x150}, | ||||
|     {&i_prci, 0x10008000, 0x14}, | ||||
|     {&i_gpio, 0x10012000, 0x44}, | ||||
|     {&i_gpio0, 0x10012000, 0x44}, | ||||
|     {&i_uart0, 0x10013000, 0x1c}, | ||||
|     {&i_qspi0, 0x10014000, 0x78}, | ||||
|     {&i_uart1, 0x10023000, 0x1c}, | ||||
|     {&i_spi, 0x10014000, 0x78}, | ||||
|     {&i_qspi1, 0x10024000, 0x78}, | ||||
|     {&i_qspi2, 0x10034000, 0x78}, | ||||
| }}; | ||||
|  | ||||
| #endif /* _E300_PLAT_MAP_H_ */ | ||||
|   | ||||
| @@ -28,7 +28,7 @@ | ||||
| // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
| // POSSIBILITY OF SUCH DAMAGE. | ||||
| // | ||||
| // Created on: Wed Oct 04 10:06:35 CEST 2017 | ||||
| // Created on: Fri Nov 10 18:01:53 CET 2017 | ||||
| //             *      gpio_regs.h Author: <RDL Generator> | ||||
| // | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -36,50 +36,53 @@ | ||||
| #ifndef _GPIO_REGS_H_ | ||||
| #define _GPIO_REGS_H_ | ||||
|  | ||||
| #include <scc/utilities.h> | ||||
| #include <util/bit_field.h> | ||||
| #include "scc/register.h" | ||||
| #include "scc/tlm_target.h" | ||||
| #include "scc/utilities.h" | ||||
| #include <scc/register.h> | ||||
| #include <scc/tlm_target.h> | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| class gpio_regs : public sc_core::sc_module, public scc::resetable { | ||||
| class gpio_regs : | ||||
|         public sc_core::sc_module, | ||||
|         public scc::resetable | ||||
| { | ||||
| public: | ||||
|     // storage declarations | ||||
|     uint32_t r_value; | ||||
|  | ||||
|      | ||||
|     uint32_t r_input_en; | ||||
|  | ||||
|      | ||||
|     uint32_t r_output_en; | ||||
|  | ||||
|      | ||||
|     uint32_t r_port; | ||||
|  | ||||
|      | ||||
|     uint32_t r_pue; | ||||
|  | ||||
|      | ||||
|     uint32_t r_ds; | ||||
|  | ||||
|      | ||||
|     uint32_t r_rise_ie; | ||||
|  | ||||
|      | ||||
|     uint32_t r_rise_ip; | ||||
|  | ||||
|      | ||||
|     uint32_t r_fall_ie; | ||||
|  | ||||
|      | ||||
|     uint32_t r_fall_ip; | ||||
|  | ||||
|      | ||||
|     uint32_t r_high_ie; | ||||
|  | ||||
|      | ||||
|     uint32_t r_high_ip; | ||||
|  | ||||
|      | ||||
|     uint32_t r_low_ie; | ||||
|  | ||||
|      | ||||
|     uint32_t r_low_ip; | ||||
|  | ||||
|      | ||||
|     uint32_t r_iof_en; | ||||
|  | ||||
|      | ||||
|     uint32_t r_iof_sel; | ||||
|  | ||||
|      | ||||
|     uint32_t r_out_xor; | ||||
|  | ||||
|      | ||||
|     // register declarations | ||||
|     scc::sc_register<uint32_t> value; | ||||
|     scc::sc_register<uint32_t> input_en; | ||||
| @@ -98,10 +101,11 @@ public: | ||||
|     scc::sc_register<uint32_t> iof_en; | ||||
|     scc::sc_register<uint32_t> iof_sel; | ||||
|     scc::sc_register<uint32_t> out_xor; | ||||
|  | ||||
|      | ||||
|     gpio_regs(sc_core::sc_module_name nm); | ||||
|  | ||||
|     template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target); | ||||
|     template<unsigned BUSWIDTH=32> | ||||
|     void registerResources(scc::tlm_target<BUSWIDTH>& target); | ||||
| }; | ||||
| } | ||||
| ////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -126,9 +130,12 @@ inline sysc::gpio_regs::gpio_regs(sc_core::sc_module_name nm) | ||||
| , NAMED(low_ip, r_low_ip, 0, *this) | ||||
| , NAMED(iof_en, r_iof_en, 0, *this) | ||||
| , NAMED(iof_sel, r_iof_sel, 0, *this) | ||||
| , NAMED(out_xor, r_out_xor, 0, *this) {} | ||||
| , NAMED(out_xor, r_out_xor, 0, *this) | ||||
| { | ||||
| } | ||||
|  | ||||
| template <unsigned BUSWIDTH> inline void sysc::gpio_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) { | ||||
| template<unsigned BUSWIDTH> | ||||
| inline void sysc::gpio_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) { | ||||
|     target.addResource(value, 0x0UL); | ||||
|     target.addResource(input_en, 0x4UL); | ||||
|     target.addResource(output_en, 0x8UL); | ||||
|   | ||||
| @@ -28,7 +28,7 @@ | ||||
| // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
| // POSSIBILITY OF SUCH DAMAGE. | ||||
| // | ||||
| // Created on: Wed Oct 04 10:06:35 CEST 2017 | ||||
| // Created on: Fri Nov 10 18:01:53 CET 2017 | ||||
| //             *      plic_regs.h Author: <RDL Generator> | ||||
| // | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -36,41 +36,45 @@ | ||||
| #ifndef _PLIC_REGS_H_ | ||||
| #define _PLIC_REGS_H_ | ||||
|  | ||||
| #include <scc/utilities.h> | ||||
| #include <util/bit_field.h> | ||||
| #include "scc/register.h" | ||||
| #include "scc/tlm_target.h" | ||||
| #include "scc/utilities.h" | ||||
| #include <scc/register.h> | ||||
| #include <scc/tlm_target.h> | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| class plic_regs : public sc_core::sc_module, public scc::resetable { | ||||
| class plic_regs : | ||||
|         public sc_core::sc_module, | ||||
|         public scc::resetable | ||||
| { | ||||
| public: | ||||
|     // storage declarations | ||||
|     BEGIN_BF_DECL(priority_t, uint32_t); | ||||
|     BF_FIELD(priority, 0, 3); | ||||
|     END_BF_DECL(); | ||||
|     std::array<priority_t, 255> r_priority; | ||||
|  | ||||
|     uint32_t r_pending; | ||||
|  | ||||
|     uint32_t r_enabled; | ||||
|  | ||||
|         BF_FIELD(priority, 0, 3); | ||||
|     END_BF_DECL() ; | ||||
|     std::array<priority_t, 256> r_priority; | ||||
|      | ||||
|     std::array<uint32_t, 8> r_pending; | ||||
|      | ||||
|     std::array<uint32_t, 8> r_enabled; | ||||
|      | ||||
|     BEGIN_BF_DECL(threshold_t, uint32_t); | ||||
|     BF_FIELD(threshold, 0, 3); | ||||
|         BF_FIELD(threshold, 0, 3); | ||||
|     END_BF_DECL() r_threshold; | ||||
|  | ||||
|      | ||||
|     uint32_t r_claim_complete; | ||||
|  | ||||
|      | ||||
|     // register declarations | ||||
|     scc::sc_register_indexed<priority_t, 255> priority; | ||||
|     scc::sc_register<uint32_t> pending; | ||||
|     scc::sc_register<uint32_t> enabled; | ||||
|     scc::sc_register_indexed<priority_t, 256> priority; | ||||
|     scc::sc_register_indexed<uint32_t, 8> pending; | ||||
|     scc::sc_register_indexed<uint32_t, 8> enabled; | ||||
|     scc::sc_register<threshold_t> threshold; | ||||
|     scc::sc_register<uint32_t> claim_complete; | ||||
|  | ||||
|      | ||||
|     plic_regs(sc_core::sc_module_name nm); | ||||
|  | ||||
|     template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target); | ||||
|     template<unsigned BUSWIDTH=32> | ||||
|     void registerResources(scc::tlm_target<BUSWIDTH>& target); | ||||
| }; | ||||
| } | ||||
| ////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -83,10 +87,13 @@ inline sysc::plic_regs::plic_regs(sc_core::sc_module_name nm) | ||||
| , NAMED(pending, r_pending, 0, *this) | ||||
| , NAMED(enabled, r_enabled, 0, *this) | ||||
| , NAMED(threshold, r_threshold, 0, *this) | ||||
| , NAMED(claim_complete, r_claim_complete, 0, *this) {} | ||||
| , NAMED(claim_complete, r_claim_complete, 0, *this) | ||||
| { | ||||
| } | ||||
|  | ||||
| template <unsigned BUSWIDTH> inline void sysc::plic_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) { | ||||
|     target.addResource(priority, 0x4UL); | ||||
| template<unsigned BUSWIDTH> | ||||
| inline void sysc::plic_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) { | ||||
|     target.addResource(priority, 0x0UL); | ||||
|     target.addResource(pending, 0x1000UL); | ||||
|     target.addResource(enabled, 0x2000UL); | ||||
|     target.addResource(threshold, 0x200000UL); | ||||
|   | ||||
| @@ -28,7 +28,7 @@ | ||||
| // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
| // POSSIBILITY OF SUCH DAMAGE. | ||||
| // | ||||
| // Created on: Wed Oct 04 10:06:35 CEST 2017 | ||||
| // Created on: Fri Nov 10 18:01:53 CET 2017 | ||||
| //             *      prci_regs.h Author: <RDL Generator> | ||||
| // | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -36,52 +36,56 @@ | ||||
| #ifndef _PRCI_REGS_H_ | ||||
| #define _PRCI_REGS_H_ | ||||
|  | ||||
| #include <scc/utilities.h> | ||||
| #include <util/bit_field.h> | ||||
| #include "scc/register.h" | ||||
| #include "scc/tlm_target.h" | ||||
| #include "scc/utilities.h" | ||||
| #include <scc/register.h> | ||||
| #include <scc/tlm_target.h> | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| class prci_regs : public sc_core::sc_module, public scc::resetable { | ||||
| class prci_regs : | ||||
|         public sc_core::sc_module, | ||||
|         public scc::resetable | ||||
| { | ||||
| public: | ||||
|     // storage declarations | ||||
|     BEGIN_BF_DECL(hfrosccfg_t, uint32_t); | ||||
|     BF_FIELD(hfroscdiv, 0, 6); | ||||
|     BF_FIELD(hfrosctrim, 16, 5); | ||||
|     BF_FIELD(hfroscen, 30, 1); | ||||
|     BF_FIELD(hfroscrdy, 31, 1); | ||||
|         BF_FIELD(hfroscdiv, 0, 6); | ||||
|         BF_FIELD(hfrosctrim, 16, 5); | ||||
|         BF_FIELD(hfroscen, 30, 1); | ||||
|         BF_FIELD(hfroscrdy, 31, 1); | ||||
|     END_BF_DECL() r_hfrosccfg; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(hfxosccfg_t, uint32_t); | ||||
|     BF_FIELD(hfxoscrdy, 31, 1); | ||||
|     BF_FIELD(hfxoscen, 30, 1); | ||||
|         BF_FIELD(hfxoscrdy, 31, 1); | ||||
|         BF_FIELD(hfxoscen, 30, 1); | ||||
|     END_BF_DECL() r_hfxosccfg; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(pllcfg_t, uint32_t); | ||||
|     BF_FIELD(pllr, 0, 3); | ||||
|     BF_FIELD(pllf, 4, 6); | ||||
|     BF_FIELD(pllq, 10, 2); | ||||
|     BF_FIELD(pllsel, 16, 1); | ||||
|     BF_FIELD(pllrefsel, 17, 1); | ||||
|     BF_FIELD(pllbypass, 18, 1); | ||||
|     BF_FIELD(plllock, 31, 1); | ||||
|         BF_FIELD(pllr, 0, 3); | ||||
|         BF_FIELD(pllf, 4, 6); | ||||
|         BF_FIELD(pllq, 10, 2); | ||||
|         BF_FIELD(pllsel, 16, 1); | ||||
|         BF_FIELD(pllrefsel, 17, 1); | ||||
|         BF_FIELD(pllbypass, 18, 1); | ||||
|         BF_FIELD(plllock, 31, 1); | ||||
|     END_BF_DECL() r_pllcfg; | ||||
|  | ||||
|      | ||||
|     uint32_t r_plloutdiv; | ||||
|  | ||||
|      | ||||
|     uint32_t r_coreclkcfg; | ||||
|  | ||||
|      | ||||
|     // register declarations | ||||
|     scc::sc_register<hfrosccfg_t> hfrosccfg; | ||||
|     scc::sc_register<hfxosccfg_t> hfxosccfg; | ||||
|     scc::sc_register<pllcfg_t> pllcfg; | ||||
|     scc::sc_register<uint32_t> plloutdiv; | ||||
|     scc::sc_register<uint32_t> coreclkcfg; | ||||
|  | ||||
|      | ||||
|     prci_regs(sc_core::sc_module_name nm); | ||||
|  | ||||
|     template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target); | ||||
|     template<unsigned BUSWIDTH=32> | ||||
|     void registerResources(scc::tlm_target<BUSWIDTH>& target); | ||||
| }; | ||||
| } | ||||
| ////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -94,9 +98,12 @@ inline sysc::prci_regs::prci_regs(sc_core::sc_module_name nm) | ||||
| , NAMED(hfxosccfg, r_hfxosccfg, 0, *this) | ||||
| , NAMED(pllcfg, r_pllcfg, 0, *this) | ||||
| , NAMED(plloutdiv, r_plloutdiv, 0, *this) | ||||
| , NAMED(coreclkcfg, r_coreclkcfg, 0, *this) {} | ||||
| , NAMED(coreclkcfg, r_coreclkcfg, 0, *this) | ||||
| { | ||||
| } | ||||
|  | ||||
| template <unsigned BUSWIDTH> inline void sysc::prci_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) { | ||||
| template<unsigned BUSWIDTH> | ||||
| inline void sysc::prci_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) { | ||||
|     target.addResource(hfrosccfg, 0x0UL); | ||||
|     target.addResource(hfxosccfg, 0x4UL); | ||||
|     target.addResource(pllcfg, 0x8UL); | ||||
|   | ||||
| @@ -28,7 +28,7 @@ | ||||
| // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
| // POSSIBILITY OF SUCH DAMAGE. | ||||
| // | ||||
| // Created on: Wed Oct 04 10:06:35 CEST 2017 | ||||
| // Created on: Fri Nov 10 18:01:53 CET 2017 | ||||
| //             *      spi_regs.h Author: <RDL Generator> | ||||
| // | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -36,93 +36,96 @@ | ||||
| #ifndef _SPI_REGS_H_ | ||||
| #define _SPI_REGS_H_ | ||||
|  | ||||
| #include <scc/utilities.h> | ||||
| #include <util/bit_field.h> | ||||
| #include "scc/register.h" | ||||
| #include "scc/tlm_target.h" | ||||
| #include "scc/utilities.h" | ||||
| #include <scc/register.h> | ||||
| #include <scc/tlm_target.h> | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| class spi_regs : public sc_core::sc_module, public scc::resetable { | ||||
| class spi_regs : | ||||
|         public sc_core::sc_module, | ||||
|         public scc::resetable | ||||
| { | ||||
| public: | ||||
|     // storage declarations | ||||
|     BEGIN_BF_DECL(sckdiv_t, uint32_t); | ||||
|     BF_FIELD(div, 0, 12); | ||||
|         BF_FIELD(div, 0, 12); | ||||
|     END_BF_DECL() r_sckdiv; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(sckmode_t, uint32_t); | ||||
|     BF_FIELD(pha, 0, 1); | ||||
|     BF_FIELD(pol, 1, 1); | ||||
|         BF_FIELD(pha, 0, 1); | ||||
|         BF_FIELD(pol, 1, 1); | ||||
|     END_BF_DECL() r_sckmode; | ||||
|  | ||||
|      | ||||
|     uint32_t r_csid; | ||||
|  | ||||
|      | ||||
|     uint32_t r_csdef; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(csmode_t, uint32_t); | ||||
|     BF_FIELD(mode, 0, 2); | ||||
|         BF_FIELD(mode, 0, 2); | ||||
|     END_BF_DECL() r_csmode; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(delay0_t, uint32_t); | ||||
|     BF_FIELD(cssck, 0, 8); | ||||
|     BF_FIELD(sckcs, 16, 8); | ||||
|         BF_FIELD(cssck, 0, 8); | ||||
|         BF_FIELD(sckcs, 16, 8); | ||||
|     END_BF_DECL() r_delay0; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(delay1_t, uint32_t); | ||||
|     BF_FIELD(intercs, 0, 16); | ||||
|     BF_FIELD(interxfr, 16, 8); | ||||
|         BF_FIELD(intercs, 0, 16); | ||||
|         BF_FIELD(interxfr, 16, 8); | ||||
|     END_BF_DECL() r_delay1; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(fmt_t, uint32_t); | ||||
|     BF_FIELD(proto, 0, 2); | ||||
|     BF_FIELD(endian, 2, 1); | ||||
|     BF_FIELD(dir, 3, 1); | ||||
|     BF_FIELD(len, 16, 4); | ||||
|         BF_FIELD(proto, 0, 2); | ||||
|         BF_FIELD(endian, 2, 1); | ||||
|         BF_FIELD(dir, 3, 1); | ||||
|         BF_FIELD(len, 16, 4); | ||||
|     END_BF_DECL() r_fmt; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(txdata_t, uint32_t); | ||||
|     BF_FIELD(data, 0, 8); | ||||
|     BF_FIELD(full, 31, 1); | ||||
|         BF_FIELD(data, 0, 8); | ||||
|         BF_FIELD(full, 31, 1); | ||||
|     END_BF_DECL() r_txdata; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(rxdata_t, uint32_t); | ||||
|     BF_FIELD(data, 0, 8); | ||||
|     BF_FIELD(empty, 31, 1); | ||||
|         BF_FIELD(data, 0, 8); | ||||
|         BF_FIELD(empty, 31, 1); | ||||
|     END_BF_DECL() r_rxdata; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(txmark_t, uint32_t); | ||||
|     BF_FIELD(txmark, 0, 3); | ||||
|         BF_FIELD(txmark, 0, 3); | ||||
|     END_BF_DECL() r_txmark; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(rxmark_t, uint32_t); | ||||
|     BF_FIELD(rxmark, 0, 3); | ||||
|         BF_FIELD(rxmark, 0, 3); | ||||
|     END_BF_DECL() r_rxmark; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(fctrl_t, uint32_t); | ||||
|     BF_FIELD(en, 0, 1); | ||||
|         BF_FIELD(en, 0, 1); | ||||
|     END_BF_DECL() r_fctrl; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(ffmt_t, uint32_t); | ||||
|     BF_FIELD(cmd_en, 0, 1); | ||||
|     BF_FIELD(addr_len, 1, 2); | ||||
|     BF_FIELD(pad_cnt, 3, 4); | ||||
|     BF_FIELD(cmd_proto, 7, 2); | ||||
|     BF_FIELD(addr_proto, 9, 2); | ||||
|     BF_FIELD(data_proto, 11, 2); | ||||
|     BF_FIELD(cmd_code, 16, 8); | ||||
|     BF_FIELD(pad_code, 24, 8); | ||||
|         BF_FIELD(cmd_en, 0, 1); | ||||
|         BF_FIELD(addr_len, 1, 2); | ||||
|         BF_FIELD(pad_cnt, 3, 4); | ||||
|         BF_FIELD(cmd_proto, 7, 2); | ||||
|         BF_FIELD(addr_proto, 9, 2); | ||||
|         BF_FIELD(data_proto, 11, 2); | ||||
|         BF_FIELD(cmd_code, 16, 8); | ||||
|         BF_FIELD(pad_code, 24, 8); | ||||
|     END_BF_DECL() r_ffmt; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(ie_t, uint32_t); | ||||
|     BF_FIELD(txwm, 0, 1); | ||||
|     BF_FIELD(rxwm, 1, 1); | ||||
|         BF_FIELD(txwm, 0, 1); | ||||
|         BF_FIELD(rxwm, 1, 1); | ||||
|     END_BF_DECL() r_ie; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(ip_t, uint32_t); | ||||
|     BF_FIELD(txwm, 0, 1); | ||||
|     BF_FIELD(rxwm, 1, 1); | ||||
|         BF_FIELD(txwm, 0, 1); | ||||
|         BF_FIELD(rxwm, 1, 1); | ||||
|     END_BF_DECL() r_ip; | ||||
|  | ||||
|      | ||||
|     // register declarations | ||||
|     scc::sc_register<sckdiv_t> sckdiv; | ||||
|     scc::sc_register<sckmode_t> sckmode; | ||||
| @@ -140,10 +143,11 @@ public: | ||||
|     scc::sc_register<ffmt_t> ffmt; | ||||
|     scc::sc_register<ie_t> ie; | ||||
|     scc::sc_register<ip_t> ip; | ||||
|  | ||||
|      | ||||
|     spi_regs(sc_core::sc_module_name nm); | ||||
|  | ||||
|     template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target); | ||||
|     template<unsigned BUSWIDTH=32> | ||||
|     void registerResources(scc::tlm_target<BUSWIDTH>& target); | ||||
| }; | ||||
| } | ||||
| ////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -167,9 +171,12 @@ inline sysc::spi_regs::spi_regs(sc_core::sc_module_name nm) | ||||
| , NAMED(fctrl, r_fctrl, 0, *this) | ||||
| , NAMED(ffmt, r_ffmt, 0, *this) | ||||
| , NAMED(ie, r_ie, 0, *this) | ||||
| , NAMED(ip, r_ip, 0, *this) {} | ||||
| , NAMED(ip, r_ip, 0, *this) | ||||
| { | ||||
| } | ||||
|  | ||||
| template <unsigned BUSWIDTH> inline void sysc::spi_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) { | ||||
| template<unsigned BUSWIDTH> | ||||
| inline void sysc::spi_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) { | ||||
|     target.addResource(sckdiv, 0x0UL); | ||||
|     target.addResource(sckmode, 0x4UL); | ||||
|     target.addResource(csid, 0x10UL); | ||||
|   | ||||
| @@ -28,7 +28,7 @@ | ||||
| // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
| // POSSIBILITY OF SUCH DAMAGE. | ||||
| // | ||||
| // Created on: Wed Oct 04 10:06:35 CEST 2017 | ||||
| // Created on: Fri Nov 10 18:01:53 CET 2017 | ||||
| //             *      uart_regs.h Author: <RDL Generator> | ||||
| // | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -36,51 +36,54 @@ | ||||
| #ifndef _UART_REGS_H_ | ||||
| #define _UART_REGS_H_ | ||||
|  | ||||
| #include <scc/utilities.h> | ||||
| #include <util/bit_field.h> | ||||
| #include "scc/register.h" | ||||
| #include "scc/tlm_target.h" | ||||
| #include "scc/utilities.h" | ||||
| #include <scc/register.h> | ||||
| #include <scc/tlm_target.h> | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| class uart_regs : public sc_core::sc_module, public scc::resetable { | ||||
| class uart_regs : | ||||
|         public sc_core::sc_module, | ||||
|         public scc::resetable | ||||
| { | ||||
| public: | ||||
|     // storage declarations | ||||
|     BEGIN_BF_DECL(txdata_t, uint32_t); | ||||
|     BF_FIELD(data, 0, 8); | ||||
|     BF_FIELD(full, 31, 1); | ||||
|         BF_FIELD(data, 0, 8); | ||||
|         BF_FIELD(full, 31, 1); | ||||
|     END_BF_DECL() r_txdata; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(rxdata_t, uint32_t); | ||||
|     BF_FIELD(data, 0, 8); | ||||
|     BF_FIELD(empty, 31, 1); | ||||
|         BF_FIELD(data, 0, 8); | ||||
|         BF_FIELD(empty, 31, 1); | ||||
|     END_BF_DECL() r_rxdata; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(txctrl_t, uint32_t); | ||||
|     BF_FIELD(txen, 0, 1); | ||||
|     BF_FIELD(nstop, 1, 1); | ||||
|     BF_FIELD(txcnt, 16, 3); | ||||
|         BF_FIELD(txen, 0, 1); | ||||
|         BF_FIELD(nstop, 1, 1); | ||||
|         BF_FIELD(txcnt, 16, 3); | ||||
|     END_BF_DECL() r_txctrl; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(rxctrl_t, uint32_t); | ||||
|     BF_FIELD(rxen, 0, 1); | ||||
|     BF_FIELD(rxcnt, 16, 3); | ||||
|         BF_FIELD(rxen, 0, 1); | ||||
|         BF_FIELD(rxcnt, 16, 3); | ||||
|     END_BF_DECL() r_rxctrl; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(ie_t, uint32_t); | ||||
|     BF_FIELD(txwm, 0, 1); | ||||
|     BF_FIELD(rxwm, 1, 1); | ||||
|         BF_FIELD(txwm, 0, 1); | ||||
|         BF_FIELD(rxwm, 1, 1); | ||||
|     END_BF_DECL() r_ie; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(ip_t, uint32_t); | ||||
|     BF_FIELD(txwm, 0, 1); | ||||
|     BF_FIELD(rxwm, 1, 1); | ||||
|         BF_FIELD(txwm, 0, 1); | ||||
|         BF_FIELD(rxwm, 1, 1); | ||||
|     END_BF_DECL() r_ip; | ||||
|  | ||||
|      | ||||
|     BEGIN_BF_DECL(div_t, uint32_t); | ||||
|     BF_FIELD(div, 0, 16); | ||||
|         BF_FIELD(div, 0, 16); | ||||
|     END_BF_DECL() r_div; | ||||
|  | ||||
|      | ||||
|     // register declarations | ||||
|     scc::sc_register<txdata_t> txdata; | ||||
|     scc::sc_register<rxdata_t> rxdata; | ||||
| @@ -89,10 +92,11 @@ public: | ||||
|     scc::sc_register<ie_t> ie; | ||||
|     scc::sc_register<ip_t> ip; | ||||
|     scc::sc_register<div_t> div; | ||||
|  | ||||
|      | ||||
|     uart_regs(sc_core::sc_module_name nm); | ||||
|  | ||||
|     template <unsigned BUSWIDTH = 32> void registerResources(scc::tlm_target<BUSWIDTH> &target); | ||||
|     template<unsigned BUSWIDTH=32> | ||||
|     void registerResources(scc::tlm_target<BUSWIDTH>& target); | ||||
| }; | ||||
| } | ||||
| ////////////////////////////////////////////////////////////////////////////// | ||||
| @@ -107,9 +111,12 @@ inline sysc::uart_regs::uart_regs(sc_core::sc_module_name nm) | ||||
| , NAMED(rxctrl, r_rxctrl, 0, *this) | ||||
| , NAMED(ie, r_ie, 0, *this) | ||||
| , NAMED(ip, r_ip, 0, *this) | ||||
| , NAMED(div, r_div, 0, *this) {} | ||||
| , NAMED(div, r_div, 0, *this) | ||||
| { | ||||
| } | ||||
|  | ||||
| template <unsigned BUSWIDTH> inline void sysc::uart_regs::registerResources(scc::tlm_target<BUSWIDTH> &target) { | ||||
| template<unsigned BUSWIDTH> | ||||
| inline void sysc::uart_regs::registerResources(scc::tlm_target<BUSWIDTH>& target) { | ||||
|     target.addResource(txdata, 0x0UL); | ||||
|     target.addResource(rxdata, 0x4UL); | ||||
|     target.addResource(txctrl, 0x8UL); | ||||
|   | ||||
| @@ -18,24 +18,34 @@ | ||||
| #define _GPIO_H_ | ||||
|  | ||||
| #include "scc/tlm_target.h" | ||||
| #include <sysc/communication/sc_signal_rv_ports.h> | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| class gpio_regs; | ||||
| class WsHandler; | ||||
|  | ||||
| class gpio : public sc_core::sc_module, public scc::tlm_target<> { | ||||
| public: | ||||
|     SC_HAS_PROCESS(gpio); | ||||
|     sc_core::sc_in<sc_core::sc_time> clk_i; | ||||
|     sc_core::sc_in<bool> rst_i; | ||||
|     sc_core::sc_inout_rv<32> pins_io; | ||||
|  | ||||
|     gpio(sc_core::sc_module_name nm); | ||||
|     virtual ~gpio() override; // need to keep it in source file because of fwd declaration of gpio_regs | ||||
|  | ||||
| protected: | ||||
|     void clock_cb(); | ||||
|     void reset_cb(); | ||||
|     void update_pins(); | ||||
|     void pins_cb(); | ||||
|     sc_core::sc_time clk; | ||||
|     std::unique_ptr<gpio_regs> regs; | ||||
|     std::shared_ptr<sysc::WsHandler> handler; | ||||
|  | ||||
| private: | ||||
| 	void update_value_reg(); | ||||
| }; | ||||
|  | ||||
| } /* namespace sysc */ | ||||
|   | ||||
| @@ -48,8 +48,8 @@ public: | ||||
|     SiFive::core_complex i_core_complex; | ||||
|     scc::router<> i_router; | ||||
|     uart i_uart0, i_uart1; | ||||
|     spi i_spi; | ||||
|     gpio i_gpio; | ||||
|     spi i_qspi0, i_qspi1, i_qspi2; | ||||
|     gpio i_gpio0; | ||||
|     plic i_plic; | ||||
|     aon i_aon; | ||||
|     prci i_prci; | ||||
| @@ -59,8 +59,9 @@ public: | ||||
|     scc::memory<128_kB, 32> i_mem_ram; | ||||
|     sc_core::sc_signal<sc_core::sc_time> s_clk; | ||||
|     sc_core::sc_signal<bool> s_rst, s_mtime_int, s_msie_int; | ||||
|     sc_core::sc_vector<sc_core::sc_signal<bool>> s_global_int; | ||||
|     sc_core::sc_vector<sc_core::sc_signal<bool>> s_global_int, s_local_int; | ||||
|     sc_core::sc_signal<bool> s_core_int; | ||||
|     sc_core::sc_signal_rv<32> s_gpio_pins; | ||||
|  | ||||
|     platform(sc_core::sc_module_name nm); | ||||
|  | ||||
|   | ||||
| @@ -22,6 +22,7 @@ | ||||
| namespace sysc { | ||||
|  | ||||
| class uart_regs; | ||||
| class WsHandler; | ||||
|  | ||||
| class uart : public sc_core::sc_module, public scc::tlm_target<> { | ||||
| public: | ||||
| @@ -38,6 +39,7 @@ protected: | ||||
|     sc_core::sc_time clk; | ||||
|     std::unique_ptr<uart_regs> regs; | ||||
|     std::vector<uint8_t> queue; | ||||
|     std::shared_ptr<sysc::WsHandler> handler; | ||||
| }; | ||||
|  | ||||
| } /* namespace sysc */ | ||||
|   | ||||
							
								
								
									
										82
									
								
								riscv.sc/incl/sysc/sc_comm_singleton.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								riscv.sc/incl/sysc/sc_comm_singleton.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| /* | ||||
|  * sc_singleton.h | ||||
|  * | ||||
|  *  Created on: 09.10.2017 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
| #ifndef RISCV_SC_INCL_SYSC_SC_COMM_SINGLETON_H_ | ||||
| #define RISCV_SC_INCL_SYSC_SC_COMM_SINGLETON_H_ | ||||
|  | ||||
| #include <sysc/kernel/sc_module.h> | ||||
| #include <seasocks/PageHandler.h> | ||||
| #include "seasocks/WebSocket.h" | ||||
|  | ||||
| #include <memory> | ||||
| #include <thread> | ||||
| #include <cstring> | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| class WsHandler: public seasocks::WebSocket::Handler { | ||||
| public: | ||||
|     explicit WsHandler() { } | ||||
|  | ||||
|     void onConnect(seasocks::WebSocket* connection) override; | ||||
|  | ||||
|     void onData(seasocks::WebSocket* connection, const char* data) override; | ||||
|  | ||||
|     void onDisconnect(seasocks::WebSocket* connection) override; | ||||
|  | ||||
|     void send(std::string msg) { for (auto *con : _connections) con->send(msg); } | ||||
|  | ||||
|     void set_receive_callback(std::function<void(const char* data)> cb){callback=cb;} | ||||
|  | ||||
| private: | ||||
|     std::set<seasocks::WebSocket*> _connections; | ||||
|     std::function<void(const char* data)> callback; | ||||
| }; | ||||
|  | ||||
| class sc_comm_singleton: public sc_core::sc_module { | ||||
| 	struct DefaultPageHandler: public seasocks::PageHandler { | ||||
| 		DefaultPageHandler(sc_comm_singleton& o):owner(o){} | ||||
| 	    virtual std::shared_ptr<seasocks::Response> handle(const seasocks::Request& request); | ||||
| 	    sc_comm_singleton& owner; | ||||
| 	}; | ||||
| public: | ||||
| 	sc_comm_singleton() = delete; | ||||
|  | ||||
| 	sc_comm_singleton(const sc_comm_singleton&) = delete; | ||||
|  | ||||
| 	sc_comm_singleton& operator=(sc_comm_singleton& o) = delete; | ||||
|  | ||||
| 	virtual ~sc_comm_singleton(); | ||||
|  | ||||
| 	static sc_comm_singleton& inst(){ | ||||
| 		static sc_comm_singleton i("__sc_singleton"); | ||||
| 		return i; | ||||
| 	} | ||||
|  | ||||
| 	seasocks::Server& get_server(); | ||||
|  | ||||
|     void registerWebSocketHandler(const char* endpoint, std::shared_ptr<seasocks::WebSocket::Handler> handler, bool allowCrossOriginRequests = false); | ||||
|  | ||||
|     void execute(std::function<void()> f); | ||||
|  | ||||
|     void start_client(); | ||||
|  | ||||
| protected: | ||||
| 	void start_of_simulation() override; | ||||
| 	void end_of_simulation() override; | ||||
|  | ||||
| private: | ||||
| 	sc_comm_singleton(sc_core::sc_module_name nm); | ||||
| 	std::unique_ptr<seasocks::Server> m_serv; | ||||
| 	std::thread t; | ||||
| 	void thread_func(); | ||||
| 	bool client_started; | ||||
| }; | ||||
|  | ||||
| } /* namespace sysc */ | ||||
|  | ||||
| #endif /* RISCV_SC_INCL_SYSC_SC_COMM_SINGLETON_H_ */ | ||||
| @@ -1,49 +0,0 @@ | ||||
| /* | ||||
|  * sc_singleton.h | ||||
|  * | ||||
|  *  Created on: 09.10.2017 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
| #ifndef RISCV_SC_INCL_SYSC_SC_SINGLETON_H_ | ||||
| #define RISCV_SC_INCL_SYSC_SC_SINGLETON_H_ | ||||
|  | ||||
| #include <sysc/kernel/sc_module.h> | ||||
| #include <memory> | ||||
| #include <thread> | ||||
|  | ||||
| namespace seasocks { | ||||
| class Server; | ||||
| } | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| class sc_singleton: public sc_core::sc_module { | ||||
| public: | ||||
| 	sc_singleton() = delete; | ||||
|  | ||||
| 	sc_singleton(const sc_singleton&) = delete; | ||||
|  | ||||
| 	sc_singleton& operator=(sc_singleton& o) = delete; | ||||
|  | ||||
| 	virtual ~sc_singleton(); | ||||
|  | ||||
| 	static sc_singleton& inst(){ | ||||
| 		static sc_singleton i("__sc_singleton"); | ||||
| 		return i; | ||||
| 	} | ||||
|  | ||||
| 	seasocks::Server& get_server(); | ||||
| protected: | ||||
| 	void start_of_simulation(); | ||||
|  | ||||
| private: | ||||
| 	sc_singleton(sc_core::sc_module_name nm); | ||||
| 	std::unique_ptr<seasocks::Server> m_serv; | ||||
| 	std::thread t; | ||||
| 	void thread_func(); | ||||
| }; | ||||
|  | ||||
| } /* namespace sysc */ | ||||
|  | ||||
| #endif /* RISCV_SC_INCL_SYSC_SC_SINGLETON_H_ */ | ||||
| @@ -56,11 +56,11 @@ int sc_main(int argc, char *argv[]) { | ||||
|             ("elf,l", po::value<std::string>(), "ELF file to load") | ||||
|             ("gdb-port,g", po::value<unsigned short>()->default_value(0), "enable gdb server and specify port to use") | ||||
|             ("dump-ir", "dump the intermediate representation") | ||||
|             ("cycles,c", po::value<int64_t>()->default_value(-1), "number of cycles to run") | ||||
|             ("cycles", po::value<int64_t>()->default_value(-1), "number of cycles to run") | ||||
|             ("quantum", po::value<unsigned>(), "SystemC quantum time in ns") | ||||
|             ("reset,r", po::value<std::string>(), "reset address") | ||||
|             ("trace,t", po::value<unsigned>()->default_value(0), "enable tracing, or combintation of 1=signals and 2=TX text, 4=TX compressed text, 6=TX in SQLite") | ||||
|             ("rv64", "run RV64") | ||||
|             ("max_time,m", po::value<std::string>(), "maximum time to run") | ||||
|             ("config-file,c", po::value<std::string>()->default_value(""), "configuration file"); | ||||
|     // clang-format on | ||||
|     po::variables_map vm; | ||||
| @@ -136,7 +136,11 @@ int sc_main(int argc, char *argv[]) { | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|     // run simulation | ||||
|     /////////////////////////////////////////////////////////////////////////// | ||||
|     sc_core::sc_start(); | ||||
|     if(vm.count("max_time")){ | ||||
|     	sc_core::sc_time max_time = scc::parse_from_string(vm["max_time"].as<std::string>()); | ||||
|     	sc_core::sc_start(max_time); | ||||
|     } else | ||||
|     	sc_core::sc_start(); | ||||
|     if (!sc_core::sc_end_of_simulation_invoked()) sc_core::sc_stop(); | ||||
|     return 0; | ||||
| } | ||||
|   | ||||
| @@ -35,7 +35,9 @@ aon::aon(sc_core::sc_module_name nm) | ||||
|     dont_initialize(); | ||||
| } | ||||
|  | ||||
| void aon::clock_cb() {} | ||||
| void aon::clock_cb() { | ||||
| 	this->clk = clk_i.read(); | ||||
| } | ||||
|  | ||||
| aon::~aon() {} | ||||
|  | ||||
|   | ||||
| @@ -17,6 +17,7 @@ | ||||
| #include "sysc/SiFive/clint.h" | ||||
|  | ||||
| #include "scc/utilities.h" | ||||
| #include "scc/report.h" | ||||
| #include "sysc/SiFive/gen/clint_regs.h" | ||||
|  | ||||
| namespace sysc { | ||||
| @@ -63,7 +64,7 @@ clint::clint(sc_core::sc_module_name nm) | ||||
|  | ||||
| void clint::clock_cb() { | ||||
|     update_mtime(); | ||||
|     clk = clk_i.read(); | ||||
|     this->clk = clk_i.read(); | ||||
|     update_mtime(); | ||||
| } | ||||
|  | ||||
| @@ -85,11 +86,14 @@ void clint::update_mtime() { | ||||
|     regs->r_mtime += (diffi + cnt_fraction) / lfclk_mutiplier; | ||||
|     cnt_fraction = (cnt_fraction + diffi) % lfclk_mutiplier; | ||||
|     mtime_evt.cancel(); | ||||
|     if (regs->r_mtimecmp > regs->r_mtime && clk > sc_core::SC_ZERO_TIME) { | ||||
|         sc_core::sc_time next_trigger = (clk * lfclk_mutiplier) * (regs->r_mtimecmp - regs->mtime) - cnt_fraction * clk; | ||||
|         mtime_evt.notify(next_trigger); | ||||
|     } else | ||||
|         mtime_int_o.write(true); | ||||
|     if (regs->r_mtimecmp > 0) | ||||
|     	if(regs->r_mtimecmp > regs->r_mtime && clk > sc_core::SC_ZERO_TIME) { | ||||
|     		sc_core::sc_time next_trigger = (clk * lfclk_mutiplier) * (regs->r_mtimecmp - regs->mtime) - cnt_fraction * clk; | ||||
|     		LOG(DEBUG)<<"Timer fires at "<< sc_time_stamp()+next_trigger; | ||||
|     		mtime_evt.notify(next_trigger); | ||||
|     		mtime_int_o.write(false); | ||||
|     	} else | ||||
|     		mtime_int_o.write(true); | ||||
|     last_updt = sc_core::sc_time_stamp(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -108,22 +108,53 @@ public: | ||||
|     }; | ||||
|  | ||||
|     iss::status read_mem(phys_addr_t addr, unsigned length, uint8_t *const data) { | ||||
|         if (addr.type & iss::DEBUG) | ||||
|             return owner->read_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err; | ||||
|         else { | ||||
|             return owner->read_mem(addr.val, length, data,addr.type && iss::FETCH) ? iss::Ok : iss::Err; | ||||
|         } | ||||
|     	if (addr.type & iss::DEBUG) | ||||
|     		return owner->read_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err; | ||||
|     	else { | ||||
|     		return owner->read_mem(addr.val, length, data,addr.type && iss::FETCH) ? iss::Ok : iss::Err; | ||||
|     	} | ||||
|     } | ||||
|  | ||||
|     iss::status write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data) { | ||||
|         if (addr.type & iss::DEBUG) | ||||
|             return owner->write_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err; | ||||
|         else | ||||
|             return owner->write_mem(addr.val, length, data) ? iss::Ok : iss::Err; | ||||
|     	if (addr.type & iss::DEBUG) | ||||
|     		return owner->write_mem_dbg(addr.val, length, data) ? iss::Ok : iss::Err; | ||||
|     	else{ | ||||
|     		auto res = owner->write_mem(addr.val, length, data) ? iss::Ok : iss::Err; | ||||
|     		// TODO: this is an ugly hack (clear MTIP on mtimecmp write), needs to be fixed | ||||
|     		if(addr.val==0x2004000) | ||||
|     			this->csr[iss::arch::mip] &= ~(1ULL<<7); | ||||
|     		return res; | ||||
|     	} | ||||
|     } | ||||
|  | ||||
|     void wait_until(uint64_t flags) { | ||||
|     	do{ | ||||
|     			wait(wfi_evt); | ||||
|     			this->check_interrupt(); | ||||
|     	} while(this->reg.pending_trap==0); | ||||
|     	base_type::wait_until(flags); | ||||
|     } | ||||
|  | ||||
|     void local_irq(short id){ | ||||
|     	switch(id){ | ||||
|     	case 16: // SW | ||||
|     		this->csr[iss::arch::mip] |= 1<<3; | ||||
|     		break; | ||||
|     	case 17: // timer | ||||
|     		this->csr[iss::arch::mip] |= 1<<7; | ||||
|     		break; | ||||
|     	case 18: //external | ||||
|     		this->csr[iss::arch::mip] |= 1<<11; | ||||
|     		break; | ||||
|     	default: | ||||
|     		/* do nothing*/ | ||||
|     		break; | ||||
|     	} | ||||
|     	wfi_evt.notify(); | ||||
|     } | ||||
| private: | ||||
|     core_complex *const owner; | ||||
|     sc_event wfi_evt; | ||||
| }; | ||||
|  | ||||
| int cmd_sysc(int argc, char* argv[], iss::debugger::out_func of, iss::debugger::data_func df, iss::debugger::target_adapter_if* tgt_adapter){ | ||||
| @@ -166,6 +197,9 @@ core_complex::core_complex(sc_core::sc_module_name name) | ||||
| , NAMED(initiator) | ||||
| , NAMED(clk_i) | ||||
| , NAMED(rst_i) | ||||
| , NAMED(global_irq_i) | ||||
| , NAMED(timer_irq_i) | ||||
| , NAMED(local_irq_i, 16) | ||||
| , NAMED(elf_file, this) | ||||
| , NAMED(enable_disass, true, this) | ||||
| , NAMED(reset_address, 0ULL, this) | ||||
| @@ -196,6 +230,12 @@ core_complex::core_complex(sc_core::sc_module_name name) | ||||
|     SC_THREAD(run); | ||||
|     SC_METHOD(clk_cb); | ||||
|     sensitive << clk_i; | ||||
|     SC_METHOD(sw_irq_cb); | ||||
|     sensitive<<sw_irq_i; | ||||
|     SC_METHOD(timer_irq_cb); | ||||
|     sensitive<<timer_irq_i; | ||||
|     SC_METHOD(global_irq_cb); | ||||
|     sensitive<<global_irq_i; | ||||
| } | ||||
|  | ||||
| core_complex::~core_complex() = default; | ||||
| @@ -242,7 +282,21 @@ void core_complex::disass_output(uint64_t pc, const std::string instr_str) { | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void core_complex::clk_cb() { curr_clk = clk_i.read(); } | ||||
| void core_complex::clk_cb() { | ||||
| 	curr_clk = clk_i.read(); | ||||
| } | ||||
|  | ||||
| void core_complex::sw_irq_cb(){ | ||||
| 	if(sw_irq_i.read()) cpu->local_irq(16); | ||||
| } | ||||
|  | ||||
| void core_complex::timer_irq_cb(){ | ||||
| 	if(timer_irq_i.read()) cpu->local_irq(17); | ||||
| } | ||||
|  | ||||
| void core_complex::global_irq_cb(){ | ||||
| 	if(timer_irq_i.read()) cpu->local_irq(18); | ||||
| } | ||||
|  | ||||
| void core_complex::run() { | ||||
|     wait(sc_core::SC_ZERO_TIME); | ||||
| @@ -268,7 +322,7 @@ bool core_complex::read_mem(uint64_t addr, unsigned length, uint8_t *const data, | ||||
|         gp.set_address(addr); | ||||
|         gp.set_data_ptr(data); | ||||
|         gp.set_data_length(length); | ||||
|         gp.set_streaming_width(4); | ||||
|         gp.set_streaming_width(length); | ||||
|         auto delay{quantum_keeper.get_local_time()}; | ||||
| #ifdef WITH_SCV | ||||
|         if(m_db!=nullptr && tr_handle.is_valid()){ | ||||
| @@ -315,7 +369,7 @@ bool core_complex::write_mem(uint64_t addr, unsigned length, const uint8_t *cons | ||||
|         gp.set_address(addr); | ||||
|         gp.set_data_ptr(write_buf.data()); | ||||
|         gp.set_data_length(length); | ||||
|         gp.set_streaming_width(4); | ||||
|         gp.set_streaming_width(length); | ||||
|         auto delay{quantum_keeper.get_local_time()}; | ||||
|         initiator->b_transport(gp, delay); | ||||
|         quantum_keeper.set(delay); | ||||
|   | ||||
| @@ -16,6 +16,8 @@ | ||||
|  | ||||
| #include "sysc/SiFive/gpio.h" | ||||
|  | ||||
| #include "sysc/sc_comm_singleton.h" | ||||
| #include "scc/report.h" | ||||
| #include "scc/utilities.h" | ||||
| #include "sysc/SiFive/gen/gpio_regs.h" | ||||
|  | ||||
| @@ -26,6 +28,7 @@ gpio::gpio(sc_core::sc_module_name nm) | ||||
| , tlm_target<>(clk) | ||||
| , NAMED(clk_i) | ||||
| , NAMED(rst_i) | ||||
| , NAMED(pins_io) | ||||
| , NAMEDD(gpio_regs, regs) { | ||||
|     regs->registerResources(*this); | ||||
|     SC_METHOD(clock_cb); | ||||
| @@ -33,9 +36,31 @@ gpio::gpio(sc_core::sc_module_name nm) | ||||
|     SC_METHOD(reset_cb); | ||||
|     sensitive << rst_i; | ||||
|     dont_initialize(); | ||||
| } | ||||
|     SC_METHOD(pins_cb); | ||||
|     sensitive << pins_io; | ||||
|  | ||||
| void gpio::clock_cb() {} | ||||
|     regs->port.set_write_cb([this](scc::sc_register<uint32_t> ®, uint32_t data) -> bool { | ||||
|         if (!this->regs->in_reset()) { | ||||
|             reg.put(data); | ||||
|             // read r_ports and update pins_io | ||||
|             update_pins(); | ||||
|         } | ||||
|         return true; | ||||
|     }); | ||||
|  | ||||
|     regs->value.set_read_cb([this](const scc::sc_register<uint32_t> ®, uint32_t& data) -> bool { | ||||
|         if (!this->regs->in_reset()) { | ||||
|         	// read pins_io and update r_value | ||||
|         	update_value_reg(); | ||||
|             data=reg.get(); | ||||
|         } | ||||
|         return true; | ||||
|     }); | ||||
|     LOG(TRACE)<<"Adding WS handler for "<<(std::string{"/ws/"}+name()); | ||||
|     handler=std::make_shared<WsHandler>(); | ||||
|     sc_comm_singleton::inst().registerWebSocketHandler((std::string{"/ws/"}+name()).c_str(), handler); | ||||
|  | ||||
| } | ||||
|  | ||||
| gpio::~gpio() {} | ||||
|  | ||||
| @@ -46,4 +71,46 @@ void gpio::reset_cb() { | ||||
|         regs->reset_stop(); | ||||
| } | ||||
|  | ||||
| void gpio::clock_cb() { | ||||
| 	this->clk = clk_i.read(); | ||||
| } | ||||
|  | ||||
| void gpio::pins_cb(){ | ||||
| 	auto inval=pins_io.read(); | ||||
| 	std::string msg(inval.to_string()); | ||||
|     sc_core::sc_time now = sc_core::sc_time_stamp(); | ||||
| 	sc_comm_singleton::inst().execute([this, msg, now](){ | ||||
| 		std::stringstream os; | ||||
| 		//os << "[" << std::setw(20) << now << "] "<<msg; | ||||
| 		os << "{\"time\":\"" << now << "\",\"data\":\""<<msg<<"\"}"; | ||||
| 		this->handler->send(os.str()); | ||||
| 	}); | ||||
| } | ||||
|  | ||||
| void gpio::update_value_reg() { | ||||
| 	// read pins_io and update r_value reg | ||||
| 	auto inval = pins_io.read(); | ||||
| 	uint32_t res = 0; | ||||
| 	for (size_t i = 0, msk = 1; i < 32; ++i, msk = msk << 1) { | ||||
| 		bool bit_set = false; | ||||
| 		if ((regs->r_input_en & msk) != 0) { | ||||
| 			if (inval.get_bit(1) == sc_dt::Log_1) | ||||
| 				bit_set = true; | ||||
| 			else if (inval.get_bit(1) == sc_dt::Log_Z | ||||
| 					&& (regs->r_pue & msk) != 0) | ||||
| 				bit_set = true; | ||||
| 		} | ||||
| 		if (bit_set) res |= msk; | ||||
| 	} | ||||
| 	regs->r_value = res; | ||||
| } | ||||
|  | ||||
| void gpio::update_pins() { | ||||
| 	sc_core::sc_inout_rv<32>::data_type out_val; | ||||
| 	for(size_t i=0, msk = 1; i<32; ++i, msk=msk<<1) | ||||
| 		out_val.set_bit(i, regs->r_output_en&msk?regs->r_port&msk?sc_dt::Log_1:sc_dt::Log_0:sc_dt::Log_Z); | ||||
| 	pins_io.write(out_val); | ||||
| } | ||||
|  | ||||
| } /* namespace sysc */ | ||||
|  | ||||
|   | ||||
| @@ -27,11 +27,13 @@ namespace sysc { | ||||
| platform::platform(sc_core::sc_module_name nm) | ||||
| : sc_core::sc_module(nm) | ||||
| , NAMED(i_core_complex) | ||||
| , NAMED(i_router, 10, 1) | ||||
| , NAMED(i_router, 12, 1) | ||||
| , NAMED(i_uart0) | ||||
| , NAMED(i_uart1) | ||||
| , NAMED(i_spi) | ||||
| , NAMED(i_gpio) | ||||
| , NAMED(i_qspi0) | ||||
| , NAMED(i_qspi1) | ||||
| , NAMED(i_qspi2) | ||||
| , NAMED(i_gpio0) | ||||
| , NAMED(i_plic) | ||||
| , NAMED(i_aon) | ||||
| , NAMED(i_prci) | ||||
| @@ -41,7 +43,9 @@ platform::platform(sc_core::sc_module_name nm) | ||||
| , NAMED(s_clk) | ||||
| , NAMED(s_rst) | ||||
| , NAMED(s_global_int, 256) | ||||
| , NAMED(s_core_int) { | ||||
| , NAMED(s_local_int, 16) | ||||
| , NAMED(s_core_int) | ||||
| , NAMED(s_gpio_pins) { | ||||
|     i_core_complex.initiator(i_router.target[0]); | ||||
|     size_t i = 0; | ||||
|     for (const auto &e : e300_plat_map) { | ||||
| @@ -56,8 +60,10 @@ platform::platform(sc_core::sc_module_name nm) | ||||
|  | ||||
|     i_uart0.clk_i(s_clk); | ||||
|     i_uart1.clk_i(s_clk); | ||||
|     i_spi.clk_i(s_clk); | ||||
|     i_gpio.clk_i(s_clk); | ||||
|     i_qspi0.clk_i(s_clk); | ||||
|     i_qspi1.clk_i(s_clk); | ||||
|     i_qspi2.clk_i(s_clk); | ||||
|     i_gpio0.clk_i(s_clk); | ||||
|     i_plic.clk_i(s_clk); | ||||
|     i_aon.clk_i(s_clk); | ||||
|     i_prci.clk_i(s_clk); | ||||
| @@ -66,8 +72,10 @@ platform::platform(sc_core::sc_module_name nm) | ||||
|  | ||||
|     i_uart0.rst_i(s_rst); | ||||
|     i_uart1.rst_i(s_rst); | ||||
|     i_spi.rst_i(s_rst); | ||||
|     i_gpio.rst_i(s_rst); | ||||
|     i_qspi0.rst_i(s_rst); | ||||
|     i_qspi1.rst_i(s_rst); | ||||
|     i_qspi2.rst_i(s_rst); | ||||
|     i_gpio0.rst_i(s_rst); | ||||
|     i_plic.rst_i(s_rst); | ||||
|     i_aon.rst_i(s_rst); | ||||
|     i_prci.rst_i(s_rst); | ||||
| @@ -79,6 +87,14 @@ platform::platform(sc_core::sc_module_name nm) | ||||
|  | ||||
|     i_plic.global_interrupts_i(s_global_int); | ||||
|     i_plic.core_interrupt_o(s_core_int); | ||||
|  | ||||
|     i_core_complex.sw_irq_i(s_msie_int); | ||||
|     i_core_complex.timer_irq_i(s_mtime_int); | ||||
|     i_core_complex.global_irq_i(s_core_int); | ||||
|     i_core_complex.local_irq_i(s_local_int); | ||||
|  | ||||
|     i_gpio0.pins_io(s_gpio_pins); | ||||
|  | ||||
|     SC_THREAD(gen_reset); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -64,7 +64,9 @@ void plic::init_callbacks() { | ||||
|     }; | ||||
| } | ||||
|  | ||||
| void plic::clock_cb() { this->clk = clk_i.read(); } | ||||
| void plic::clock_cb() { | ||||
| 	this->clk = clk_i.read(); | ||||
| } | ||||
|  | ||||
| void plic::reset_cb() { | ||||
|     if (rst_i.read()) | ||||
| @@ -92,14 +94,13 @@ void plic::reset_cb() { | ||||
| void plic::global_int_port_cb() { | ||||
|  | ||||
|     // set related pending bit if enable is set for incoming global_interrupt | ||||
|  | ||||
|     // todo: extend up to 255 bits (limited to 32 right now) | ||||
|     for (uint32_t i = 1; i < 32; i++) { | ||||
|         uint32_t enable_bits = regs->r_enabled; | ||||
|         bool enable = enable_bits & (0x1 << i); // read enable bit | ||||
|     for (uint32_t i = 1; i < 256; i++) { | ||||
|     	auto reg_idx = i>>5; | ||||
|     	auto bit_ofs = i & 0x1F; | ||||
|         bool enable = regs->r_enabled[reg_idx] & (0x1 << bit_ofs); // read enable bit | ||||
|  | ||||
|         if (enable && global_interrupts_i[i].read() == 1) { | ||||
|             regs->r_pending = regs->r_pending | (0x1 << i); | ||||
|             regs->r_pending[reg_idx] = regs->r_pending[reg_idx] | (0x1 << bit_ofs); | ||||
|             LOG(DEBUG) << "pending interrupt identified: " << i; | ||||
|         } | ||||
|     } | ||||
| @@ -114,14 +115,14 @@ void plic::handle_pending_int() { | ||||
|     bool raise_int = 0; | ||||
|     uint32_t thold = regs->r_threshold.threshold; // threshold value | ||||
|  | ||||
|     // todo: extend up to 255 bits (limited to 32 right now) | ||||
|     for (uint32_t i = 1; i < 32; i++) { | ||||
|         uint32_t pending_bits = regs->r_pending; | ||||
|         bool pending = (pending_bits & (0x1 << i)) ? true : false; | ||||
|     for (uint32_t i = 1; i < 255; i++) { | ||||
|     	auto reg_idx = i>>5; | ||||
|     	auto bit_ofs = i & 0x1F; | ||||
|         bool pending = (regs->r_pending[reg_idx] & (0x1 << bit_ofs)) ? true : false; | ||||
|         uint32_t prio = regs->r_priority[i - 1].priority; // read priority value | ||||
|  | ||||
|         if (pending && thold < prio) { | ||||
|             regs->r_pending = regs->r_pending | (0x1 << i); | ||||
|             regs->r_pending[reg_idx] = regs->r_pending[reg_idx] | (0x1 << bit_ofs); | ||||
|             // below condition ensures implicitly that lowest id is selected in case of multiple identical | ||||
|             // priority-interrupts | ||||
|             if (prio > claim_prio) { | ||||
| @@ -148,7 +149,9 @@ void plic::reset_pending_int(uint32_t irq) { | ||||
|     // todo: make sure that pending is set, otherwise don't reset irq ... read spec. | ||||
|     LOG(INFO) << "reset pending interrupt: " << irq; | ||||
|     // reset related pending bit | ||||
|     regs->r_pending &= ~(0x1 << irq); | ||||
| 	auto reg_idx = irq>>5; | ||||
| 	auto bit_ofs = irq & 0x1F; | ||||
|     regs->r_pending[reg_idx] &= ~(0x1 << bit_ofs); | ||||
|     core_interrupt_o.write(0); | ||||
|  | ||||
|     // evaluate next pending interrupt | ||||
|   | ||||
| @@ -54,7 +54,10 @@ prci::prci(sc_core::sc_module_name nm) | ||||
|     }); | ||||
| } | ||||
|  | ||||
| void prci::clock_cb() {} | ||||
| void prci::clock_cb() { | ||||
| 	this->clk = clk_i.read(); | ||||
|  | ||||
| } | ||||
|  | ||||
| prci::~prci() {} | ||||
|  | ||||
|   | ||||
							
								
								
									
										153
									
								
								riscv.sc/src/sysc/sc_comm_singleton.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								riscv.sc/src/sysc/sc_comm_singleton.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,153 @@ | ||||
| /* | ||||
|  * sc_singleton.cpp | ||||
|  * | ||||
|  *  Created on: 09.10.2017 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
| #include "sysc/sc_comm_singleton.h" | ||||
|  | ||||
| #include "seasocks/PrintfLogger.h" | ||||
| #include "seasocks/Server.h" | ||||
| #include "seasocks/StringUtil.h" | ||||
| #include "seasocks/util/Json.h" | ||||
| #include "seasocks/ResponseWriter.h" | ||||
| #include "seasocks/util/RootPageHandler.h" | ||||
| #include "seasocks/util/CrackedUriPageHandler.h" | ||||
| #include "seasocks/util/StaticResponseHandler.h" | ||||
|  | ||||
| #include <cstdio> | ||||
| #include <csignal> | ||||
| #include <sys/stat.h> | ||||
| #include <cerrno> | ||||
| #include <fcntl.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| using namespace seasocks; | ||||
| using namespace std; | ||||
|  | ||||
| namespace { | ||||
| inline void die(){perror(nullptr);exit(errno);} | ||||
| } | ||||
|  | ||||
| sc_comm_singleton::sc_comm_singleton(sc_core::sc_module_name nm) | ||||
| : sc_core::sc_module(nm) | ||||
| , m_serv(new Server(std::make_shared<PrintfLogger>(Logger::Level::WARNING))) | ||||
| , client_started(false){ | ||||
| 	m_serv->addPageHandler(std::make_shared<DefaultPageHandler>(*this)); | ||||
| } | ||||
|  | ||||
| sc_comm_singleton::~sc_comm_singleton() { | ||||
| 	//Join the thread with the main thread | ||||
| 	t.join(); | ||||
| } | ||||
|  | ||||
| void sc_comm_singleton::start_of_simulation() { | ||||
| 	//Launch a thread | ||||
| 	t=std::thread(&sc_comm_singleton::thread_func, this); | ||||
| 	start_client(); | ||||
| } | ||||
|  | ||||
| void sc_comm_singleton::end_of_simulation() { | ||||
| 	get_server().terminate(); | ||||
| } | ||||
|  | ||||
| void sc_comm_singleton::start_client() { | ||||
| 	if(client_started) return; | ||||
| 	std::stringstream ss; | ||||
| #ifndef WIN32 | ||||
| 	if(fork()==0){ | ||||
| 		// daemonizing, see http://www.microhowto.info/howto/cause_a_process_to_become_a_daemon_in_c.html#id2407077 | ||||
| 	    // Fork, allowing the parent process to terminate. | ||||
| 	    pid_t pid = fork(); | ||||
| 	    if (pid == -1) { | ||||
| 	        die(); | ||||
| 	    } else if (pid != 0) { | ||||
| 	        _exit(0); | ||||
| 	    } | ||||
| 	    // Start a new session for the daemon. | ||||
| 	    if (setsid()==-1) die(); | ||||
| 	    // Fork again, allowing the parent process to terminate. | ||||
| 	    signal(SIGHUP,SIG_IGN); | ||||
| 	    pid=fork(); | ||||
| 	    if (pid == -1) { | ||||
| 	        die(); | ||||
| 	    } else if (pid != 0) { | ||||
| 	        _exit(0); | ||||
| 	    } | ||||
| 	    // Set the current working directory to the root directory. | ||||
| 	    if (chdir("/") == -1) die(); | ||||
| 	    // Set the user file creation mask to zero. | ||||
| 	    umask(0); | ||||
|  | ||||
| 	    // Close then reopen standard file descriptors. | ||||
| 	    close(STDIN_FILENO); | ||||
| 	    close(STDOUT_FILENO); | ||||
| 	    close(STDERR_FILENO); | ||||
| 	    if (open("/dev/null",O_RDONLY) == -1) die(); | ||||
| 	    if (open("/dev/null",O_WRONLY) == -1) die(); | ||||
| 	    if (open("/dev/null",O_RDWR) == -1)  die(); | ||||
| 		// now do what is needed | ||||
| 		ss<<"x-www-browser http://localhost:9090/ws.html"; //Linux | ||||
| 		auto res = system (ss.str().c_str()); | ||||
| 		if(res==0) exit(0); | ||||
| 		ss.str(""); | ||||
| 		ss<<"xdg-open  http://localhost:9090/ws.html"; // Linux | ||||
| 		res=system (ss.str().c_str()); | ||||
| 		if(res==0) exit(0); | ||||
| 		ss.str(""); | ||||
| 		ss<<"open  http://localhost:9090/ws.html"; // MacOS | ||||
| 		res=system (ss.str().c_str()); | ||||
| 		exit(0); | ||||
| 	} | ||||
| 	// #else | ||||
| 	// on windows should be open, see https://www.experts-exchange.com/articles/1595/Execute-a-Program-with-C.html | ||||
| #endif | ||||
| 	client_started=true; | ||||
| } | ||||
|  | ||||
| void sc_comm_singleton::registerWebSocketHandler(const char* endpoint, | ||||
| 		std::shared_ptr<WebSocket::Handler> handler, | ||||
| 		bool allowCrossOriginRequests) { | ||||
| 	get_server().addWebSocketHandler(endpoint, handler, allowCrossOriginRequests); | ||||
| } | ||||
|  | ||||
| void sc_comm_singleton::execute(std::function<void()> f) { | ||||
| 	get_server().execute(f); | ||||
| } | ||||
|  | ||||
| void sc_comm_singleton::thread_func() { | ||||
| 	get_server().serve("./html", 9090); | ||||
| } | ||||
|  | ||||
| Server& sc_comm_singleton::get_server() { | ||||
| 	return *m_serv.get(); | ||||
| } | ||||
|  | ||||
|  | ||||
| std::shared_ptr<Response> sc_comm_singleton::DefaultPageHandler::handle(const Request& request) { | ||||
| 	if(request.verb() == Request::Verb::Get && request.getRequestUri()=="conf.json"){ | ||||
| 		return Response::htmlResponse("{}"); | ||||
| 	} | ||||
| 	return Response::unhandled(); | ||||
| } | ||||
|  | ||||
| void WsHandler::onConnect(WebSocket* connection) { | ||||
| 	_connections.insert(connection); | ||||
| 	//connection->send("Connection established");; | ||||
| } | ||||
|  | ||||
| void WsHandler::onData(WebSocket* connection, const char* data) { | ||||
| 	if (0 == strcmp("close", data)) { | ||||
| 		connection->close(); | ||||
| 	} else if(callback) | ||||
| 		callback(data); | ||||
| } | ||||
|  | ||||
| void WsHandler::onDisconnect(WebSocket* connection) { | ||||
| 	_connections.erase(connection); | ||||
| } | ||||
|  | ||||
| } /* namespace sysc */ | ||||
| @@ -1,57 +0,0 @@ | ||||
| /* | ||||
|  * sc_singleton.cpp | ||||
|  * | ||||
|  *  Created on: 09.10.2017 | ||||
|  *      Author: eyck | ||||
|  */ | ||||
|  | ||||
| #include "sysc/sc_singleton.h" | ||||
|  | ||||
| #include "seasocks/PrintfLogger.h" | ||||
| #include "seasocks/Server.h" | ||||
| #include "seasocks/StringUtil.h" | ||||
| #include "seasocks/util/Json.h" | ||||
| #include "seasocks/ResponseWriter.h" | ||||
| #include "seasocks/util/RootPageHandler.h" | ||||
| #include "seasocks/util/CrackedUriPageHandler.h" | ||||
| #include "seasocks/util/StaticResponseHandler.h" | ||||
|  | ||||
| namespace sysc { | ||||
|  | ||||
| using namespace seasocks; | ||||
| using namespace std; | ||||
|  | ||||
| namespace { | ||||
| const std::string MSG_TXT { "Hello World"}; | ||||
| } | ||||
|  | ||||
| void sc_singleton::start_of_simulation() { | ||||
| 	//Launch a thread | ||||
| 	t=std::thread(&sc_singleton::thread_func, this); | ||||
|  | ||||
| } | ||||
|  | ||||
| sc_singleton::sc_singleton(sc_core::sc_module_name nm) | ||||
| : sc_core::sc_module(nm) | ||||
| , m_serv(new seasocks::Server(std::make_shared<PrintfLogger>(Logger::Level::DEBUG))){ | ||||
| 	auto rootHandler = make_shared<seasocks::RootPageHandler>(); | ||||
| 	rootHandler->add(std::shared_ptr<CrackedUriPageHandler>(new StaticResponseHandler("/", Response::textResponse(MSG_TXT)))); | ||||
| 	m_serv->addPageHandler(rootHandler); | ||||
| } | ||||
|  | ||||
| sc_singleton::~sc_singleton() { | ||||
| 	//Join the thread with the main thread | ||||
| 	t.join(); | ||||
| } | ||||
|  | ||||
| void sc_singleton::thread_func() { | ||||
| 	get_server().serve(".", 9090); | ||||
| } | ||||
|  | ||||
| seasocks::Server& sc_singleton::get_server() { | ||||
| 	return *m_serv.get(); | ||||
| } | ||||
|  | ||||
|  | ||||
| } /* namespace sysc */ | ||||
|  | ||||
| @@ -37,7 +37,9 @@ spi::spi(sc_core::sc_module_name nm) | ||||
|  | ||||
| spi::~spi() {} | ||||
|  | ||||
| void spi::clock_cb() { this->clk = clk_i.read(); } | ||||
| void spi::clock_cb() { | ||||
| 	this->clk = clk_i.read(); | ||||
| } | ||||
|  | ||||
| void spi::reset_cb() { | ||||
|     if (rst_i.read()) | ||||
|   | ||||
| @@ -16,76 +16,19 @@ | ||||
|  | ||||
| #include "sysc/SiFive/uart.h" | ||||
|  | ||||
| #include "sysc/sc_comm_singleton.h" | ||||
| #include "scc/report.h" | ||||
| #include "scc/utilities.h" | ||||
| #include "sysc/SiFive/gen/uart_regs.h" | ||||
| #include "sysc/sc_singleton.h" | ||||
|  | ||||
| #include "seasocks/PrintfLogger.h" | ||||
| #include "seasocks/Server.h" | ||||
| #include "seasocks/StringUtil.h" | ||||
| #include "seasocks/WebSocket.h" | ||||
| #include "seasocks/util/Json.h" | ||||
| using namespace std; | ||||
|  | ||||
|  | ||||
| namespace sysc { | ||||
| namespace { | ||||
|  | ||||
| using namespace seasocks; | ||||
|  | ||||
| class MyHandler: public WebSocket::Handler { | ||||
| public: | ||||
|     explicit MyHandler(Server* server) : _server(server), _currentValue(0) { | ||||
|         setValue(1); | ||||
|     } | ||||
|  | ||||
|     virtual void onConnect(WebSocket* connection) { | ||||
|         _connections.insert(connection); | ||||
|         connection->send(_currentSetValue.c_str()); | ||||
|         cout << "Connected: " << connection->getRequestUri() | ||||
|                 << " : " << formatAddress(connection->getRemoteAddress()) | ||||
|                 << endl; | ||||
|         cout << "Credentials: " << *(connection->credentials()) << endl; | ||||
|     } | ||||
|  | ||||
|     virtual void onData(WebSocket* connection, const char* data) { | ||||
|         if (0 == strcmp("die", data)) { | ||||
|             _server->terminate(); | ||||
|             return; | ||||
|         } | ||||
|         if (0 == strcmp("close", data)) { | ||||
|             cout << "Closing.." << endl; | ||||
|             connection->close(); | ||||
|             cout << "Closed." << endl; | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         int value = atoi(data) + 1; | ||||
|         if (value > _currentValue) { | ||||
|             setValue(value); | ||||
|             for (auto c : _connections) { | ||||
|                 c->send(_currentSetValue.c_str()); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     virtual void onDisconnect(WebSocket* connection) { | ||||
|         _connections.erase(connection); | ||||
|         cout << "Disconnected: " << connection->getRequestUri() | ||||
|                 << " : " << formatAddress(connection->getRemoteAddress()) | ||||
|                 << endl; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     set<WebSocket*> _connections; | ||||
|     Server* _server; | ||||
|     int _currentValue; | ||||
|     string _currentSetValue; | ||||
|  | ||||
|     void setValue(int value) { | ||||
|         _currentValue = value; | ||||
|         _currentSetValue = makeExecString("set", _currentValue); | ||||
|     } | ||||
| }; | ||||
|  | ||||
| } | ||||
| uart::uart(sc_core::sc_module_name nm) | ||||
| @@ -107,15 +50,16 @@ uart::uart(sc_core::sc_module_name nm) | ||||
|         } | ||||
|         return true; | ||||
|     }); | ||||
|     auto& server = sc_singleton::inst().get_server(); | ||||
|     auto handler = std::make_shared<MyHandler>(&server); | ||||
|     server.addWebSocketHandler((std::string{"/ws/"}+name()).c_str(), handler); | ||||
|  | ||||
|     LOG(TRACE)<<"Adding WS handler for "<<(std::string{"/ws/"}+name()); | ||||
|     handler=std::make_shared<WsHandler>(); | ||||
|     sc_comm_singleton::inst().registerWebSocketHandler((std::string{"/ws/"}+name()).c_str(), handler); | ||||
| } | ||||
|  | ||||
| uart::~uart() {} | ||||
|  | ||||
| void uart::clock_cb() { this->clk = clk_i.read(); } | ||||
| void uart::clock_cb() { | ||||
| 	this->clk = clk_i.read(); | ||||
| } | ||||
|  | ||||
| void uart::reset_cb() { | ||||
|     if (rst_i.read()) | ||||
| @@ -127,7 +71,14 @@ void uart::reset_cb() { | ||||
| void uart::transmit_data() { | ||||
|     if(regs->r_txdata.data != '\r') queue.push_back(regs->r_txdata.data); | ||||
|     if (queue.size() >> 0 && (regs->r_txdata.data == '\n' || regs->r_txdata.data == 0)) { | ||||
|         LOG(INFO) << this->name() << " transmit: '" << std::string(queue.begin(), queue.end()) << "'"; | ||||
|     	std::string msg(queue.begin(), queue.end()-1); | ||||
|         LOG(INFO) << this->name() << " transmit: '" << msg << "'"; | ||||
|         sc_core::sc_time now = sc_core::sc_time_stamp(); | ||||
| 		sc_comm_singleton::inst().execute([this, msg, now](){ | ||||
| 			std::stringstream os; | ||||
| 			os << "{\"time\":\"" << now << "\",\"message\":\""<<msg<<"\"}"; | ||||
| 			this->handler->send(os.str()); | ||||
| 		}); | ||||
|         queue.clear(); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -161,22 +161,22 @@ namespace { | ||||
|  | ||||
| const char lvl[] = {'U', 'S', 'H', 'M'}; | ||||
|  | ||||
| const char *trap_str[] = {"Instruction address misaligned", | ||||
|                           "Instruction access fault", | ||||
|                           "Illegal instruction", | ||||
|                           "Breakpoint", | ||||
|                           "Load address misaligned", | ||||
|                           "Load access fault", | ||||
|                           "Store/AMO address misaligned", | ||||
|                           "Store/AMO access fault", | ||||
|                           "Environment call from U-mode", | ||||
|                           "Environment call from S-mode", | ||||
|                           "Reserved", | ||||
|                           "Environment call from M-mode", | ||||
|                           "Instruction page fault", | ||||
|                           "Load page fault", | ||||
|                           "Reserved", | ||||
|                           "Store/AMO page fault"}; | ||||
| const char *trap_str[] = {"Instruction address misaligned", //0 | ||||
|                           "Instruction access fault", //1 | ||||
|                           "Illegal instruction", //2 | ||||
|                           "Breakpoint", //3 | ||||
|                           "Load address misaligned", //4 | ||||
|                           "Load access fault", //5 | ||||
|                           "Store/AMO address misaligned", //6 | ||||
|                           "Store/AMO access fault", //7 | ||||
|                           "Environment call from U-mode", //8 | ||||
|                           "Environment call from S-mode", //9 | ||||
|                           "Reserved", //a | ||||
|                           "Environment call from M-mode", //b | ||||
|                           "Instruction page fault", //c | ||||
|                           "Load page fault", //d | ||||
|                           "Reserved", //e | ||||
|                           "Store/AMO page fault"}; //f | ||||
| const char *irq_str[] = { | ||||
|     "User software interrupt", "Supervisor software interrupt", "Reserved", "Machine software interrupt", | ||||
|     "User timer interrupt",    "Supervisor timer interrupt",    "Reserved", "Machine timer interrupt", | ||||
| @@ -479,6 +479,7 @@ private: | ||||
|     iss::status write_ip(unsigned addr, reg_t val); | ||||
|     iss::status read_satp(unsigned addr, reg_t &val); | ||||
|     iss::status write_satp(unsigned addr, reg_t val); | ||||
| protected: | ||||
|     void check_interrupt(); | ||||
| }; | ||||
|  | ||||
| @@ -682,7 +683,7 @@ iss::status riscv_hart_msu_vp<BASE>::write(const iss::addr_t &addr, unsigned len | ||||
|                 } | ||||
|                 phys_addr_t paddr = (addr.type & iss::ADDRESS_TYPE) == iss::PHYSICAL ? addr : v2p(addr); | ||||
|                 auto res = write_mem(paddr, length, data); | ||||
|                 if (res != iss::Ok) this->reg.trap_state = (1 << 31) | (7 << 16); // issue trap 7 (load access fault | ||||
|                 if (res != iss::Ok) this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 7 (Store/AMO access fault) | ||||
|                 return res; | ||||
|             } catch (trap_access &ta) { | ||||
|                 this->reg.trap_state = (1 << 31) | ta.id; | ||||
| @@ -848,6 +849,7 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_ip(unsigned | ||||
|     auto req_priv_lvl = addr >> 8; | ||||
|     if (this->reg.machine_state < req_priv_lvl) throw illegal_instruction_fault(this->fault_data); | ||||
|     auto mask = get_irq_mask(req_priv_lvl); | ||||
|     mask &= ~(1<<7); // MTIP is read only | ||||
|     csr[mip] = (csr[mip] & ~mask) | (val & mask); | ||||
|     check_interrupt(); | ||||
|     return iss::Ok; | ||||
| @@ -1142,7 +1144,8 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f | ||||
|         csr[uepc | (new_priv << 8)] = this->reg.NEXT_PC; // store next address if interrupt | ||||
|         this->reg.pending_trap = 0; | ||||
|     } | ||||
|     csr[ucause | (new_priv << 8)] = cause; | ||||
|     size_t adr=ucause | (new_priv << 8); | ||||
|     csr[adr] = (trap_id<<31)+cause; | ||||
|     // update mstatus | ||||
|     // xPP field of mstatus is written with the active privilege mode at the time | ||||
|     // of the trap; the x PIE field of mstatus | ||||
| @@ -1177,8 +1180,8 @@ template <typename BASE> uint64_t riscv_hart_msu_vp<BASE>::enter_trap(uint64_t f | ||||
|     this->reg.trap_state = 0; | ||||
|     char buffer[32]; | ||||
|     sprintf(buffer, "0x%016lx", addr); | ||||
|     CLOG(INFO, disass) << (trap_id ? "Interrupt " : "Trap ") << " with cause '" << (trap_id ? irq_str[cause] : trap_str[cause]) | ||||
|                        << "' at address " << buffer << " occurred, changing privilege level from " << lvl[cur_priv] | ||||
|     CLOG(INFO, disass) << (trap_id ? "Interrupt" : "Trap") << " with cause '" << (trap_id ? irq_str[cause] : trap_str[cause])<<"' ("<<trap_id<<")" | ||||
|                        << " at address " << buffer << " occurred, changing privilege level from " << lvl[cur_priv] | ||||
|                        << " to " << lvl[new_priv]; | ||||
|     return this->reg.NEXT_PC; | ||||
| } | ||||
|   | ||||
 Submodule sc-components updated: 30ebb87f76...174e0f55f1
									
								
							
		Reference in New Issue
	
	Block a user