Added SystemC version of HiFive FE310
This commit is contained in:
		
							
								
								
									
										158
									
								
								riscv.sc/gen_input/aon.rdl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								riscv.sc/gen_input/aon.rdl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,158 @@ | |||||||
|  | regfile aon_regs { | ||||||
|  | 	// Watchdog Timer Registers | ||||||
|  | 	reg { | ||||||
|  | 		name = "wdogcfg"; | ||||||
|  | 		desc = "Watchdog Timer Config Register"; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	} wdogcfg @0x00; | ||||||
|  | 	reg { | ||||||
|  | 		name ="wdogcount"; | ||||||
|  | 		desc = "Watchdog Timer Count Registers"; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	} wdogcount @0x08;  | ||||||
|  | 	reg { | ||||||
|  | 		name ="wdogs"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	} wdogs @0x10;  | ||||||
|  | 	reg { | ||||||
|  | 		name ="wdogfeed"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	} wdogfeed @0x18;  | ||||||
|  | 	reg { | ||||||
|  | 		name ="wdogkey"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	} wdogkey @0x1C;  | ||||||
|  | 	reg { | ||||||
|  | 		name ="wdogcmp"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	} wdogcmp @0x20; | ||||||
|  | 	// Real-Time Clock Registers | ||||||
|  | 	reg { | ||||||
|  | 		name ="rtccfg"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	} rtccfg @0x40; | ||||||
|  | 	reg { | ||||||
|  | 		name ="rtclo"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	}  rtclo @0x48; | ||||||
|  |  	reg { | ||||||
|  | 		name ="rtchi"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	} rtchi @0x4C; | ||||||
|  | 	reg { | ||||||
|  | 		name ="rtcs"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	}  rtcs @0x50; | ||||||
|  | 	reg { | ||||||
|  | 		name ="rtccmp"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	} rtccmp @0x60; | ||||||
|  | 	// AON Clock Configuration Registers | ||||||
|  | 	reg { | ||||||
|  | 		name ="lfrosccfg"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	} lfrosccfg @0x70; | ||||||
|  | 	// Backup Registers | ||||||
|  | 	reg { | ||||||
|  | 		name ="lfrosccfg"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	} backup[32] @0x80; | ||||||
|  | 	// Power Management Unit | ||||||
|  | 	reg { | ||||||
|  | 		name ="pmuwakeupi"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="delay"; | ||||||
|  | 		} delay[3:0]; | ||||||
|  | 		field { | ||||||
|  | 			name="vddpaden"; | ||||||
|  | 		} vddpaden[5:5]; | ||||||
|  | 		field { | ||||||
|  | 			name="corerst"; | ||||||
|  | 		} corerst[7:7]; | ||||||
|  | 		field { | ||||||
|  | 			name="hfclkrst"; | ||||||
|  | 		} hfclkrst[8:8]; | ||||||
|  | 	} pmuwakeupi[8] @0x0100; | ||||||
|  | 	reg { | ||||||
|  | 		name ="pmusleepi"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="delay"; | ||||||
|  | 		} delay[3:0]; | ||||||
|  | 		field { | ||||||
|  | 			name="vddpaden"; | ||||||
|  | 		} vddpaden[5:5]; | ||||||
|  | 		field { | ||||||
|  | 			name="corerst"; | ||||||
|  | 		} corerst[7:7]; | ||||||
|  | 		field { | ||||||
|  | 			name="hfclkrst"; | ||||||
|  | 		} hfclkrst[8:8]; | ||||||
|  | 	} pmusleepi[8] @0x0120; | ||||||
|  | 	reg { | ||||||
|  | 		name ="pmuie"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	} pmuie @0x0140; | ||||||
|  | 	reg { | ||||||
|  | 		name ="pmucause"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	} pmucause @0x0144; | ||||||
|  | 	reg { | ||||||
|  | 		name ="pmusleep"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	} pmusleep @0x0148; | ||||||
|  | 	reg { | ||||||
|  | 		name ="pmukey"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	} pmukey @0x014C; | ||||||
|  | }; | ||||||
							
								
								
									
										27
									
								
								riscv.sc/gen_input/clint.rdl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								riscv.sc/gen_input/clint.rdl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | |||||||
|  | regfile clint_regs { | ||||||
|  | 	reg { | ||||||
|  | 		name = "msip"; | ||||||
|  | 		desc = "Hart 0 software interrupt register"; | ||||||
|  | 		field { | ||||||
|  | 			name="msip"; | ||||||
|  | 		} msip[0:0]; | ||||||
|  | 	} msip @0; | ||||||
|  | 	reg { | ||||||
|  | 		name = "mtimecmp"; | ||||||
|  | 		desc = "Hart 0 time comparator register"; | ||||||
|  | 		regwidth=64; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 			fieldwidth=64; | ||||||
|  | 		} data = 64'h7FFFFFFFFFFFFFFF; | ||||||
|  | 	} mtimecmp @0x4000; | ||||||
|  | 	reg { | ||||||
|  | 		name = "mtime"; | ||||||
|  | 		desc = "Timer register"; | ||||||
|  | 		regwidth=64; | ||||||
|  | 		field { | ||||||
|  | 			fieldwidth=64; | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[63:0]; | ||||||
|  | 	} mtime @0xBFF8; | ||||||
|  | }; | ||||||
| @@ -2,10 +2,18 @@ | |||||||
| `include "uart.rdl" | `include "uart.rdl" | ||||||
| `include "spi.rdl" | `include "spi.rdl" | ||||||
| `include "plic.rdl" | `include "plic.rdl" | ||||||
|  | `include "aon.rdl" | ||||||
|  | `include "prci.rdl" | ||||||
|  | `include "clint.rdl" | ||||||
|  |  | ||||||
| addrmap e300_plat_t { | addrmap e300_plat_t { | ||||||
|  | 	lsb0; | ||||||
|  | 	clint_regs clint @0x02000000; | ||||||
|     plic_regs  plic  @0x0C000000; |     plic_regs  plic  @0x0C000000; | ||||||
|  |     aon_regs   aon   @0x10000000; | ||||||
|  |     prci_regs  prci  @0x10008000; | ||||||
|     gpio_regs  gpio  @0x10012000; |     gpio_regs  gpio  @0x10012000; | ||||||
|     uart_regs uart @0x10013000; |     uart_regs  uart0 @0x10013000; | ||||||
|  |     uart_regs  uart1 @0x10023000; | ||||||
|     spi_regs   spi   @0x10014000;   |     spi_regs   spi   @0x10014000;   | ||||||
| } e300_plat; | } e300_plat; | ||||||
|   | |||||||
| @@ -1,5 +1,4 @@ | |||||||
| regfile gpio_regs { | regfile gpio_regs { | ||||||
| 	lsb0; |  | ||||||
| 	reg { | 	reg { | ||||||
| 		name="value"; | 		name="value"; | ||||||
| 		desc="pin value"; | 		desc="pin value"; | ||||||
|   | |||||||
| @@ -2,36 +2,26 @@ regfile plic_regs { | |||||||
| 	reg { | 	reg { | ||||||
| 		name="priority"; | 		name="priority"; | ||||||
| 		desc="interrupt source priority"; | 		desc="interrupt source priority"; | ||||||
| 		field { | 		field {} priority[2:0]; | ||||||
| 			name = "priority"; |  | ||||||
| 		} priority[2:0]; |  | ||||||
| 	} priority[255] @0x004; | 	} priority[255] @0x004; | ||||||
| 	reg { | 	reg { | ||||||
| 		name="pending"; | 		name="pending"; | ||||||
| 		desc="pending irq"; | 		desc="pending irq"; | ||||||
| 		field { | 		field {} pending[31:0]; | ||||||
| 			name = "pending"; |  | ||||||
| 		} pending[31:0]; |  | ||||||
| 	} pending @0x1000; | 	} pending @0x1000; | ||||||
| 	reg { | 	reg { | ||||||
| 		name="enabled"; | 		name="enabled"; | ||||||
| 		desc="enabled interrupts"; | 		desc="enabled interrupts"; | ||||||
| 		field { | 		field {} enabled[31:0]; | ||||||
| 			name = "enabled"; |  | ||||||
| 		} enabled[31:0]; |  | ||||||
| 	} enabled @0x2000; | 	} enabled @0x2000; | ||||||
| 	reg { | 	reg { | ||||||
| 		name="threshold"; | 		name="threshold"; | ||||||
| 		desc="interrupt priority threshold"; | 		desc="interrupt priority threshold"; | ||||||
| 		field { | 		field {} \threshold[2:0]; | ||||||
| 			name = "threshold"; |  | ||||||
| 		} \threshold[2:0]; |  | ||||||
| 	} \threshold @0x200000; | 	} \threshold @0x200000; | ||||||
| 	reg { | 	reg { | ||||||
| 		name="claim/complete"; | 		name="claim/complete"; | ||||||
| 		desc="interrupt handling completed"; | 		desc="interrupt handling completed"; | ||||||
| 		field { | 		field {} interrupt_claimed[31:0]; | ||||||
| 			name = "interrupt_claimed"; |  | ||||||
| 		} interrupt_claimed[31:0]; |  | ||||||
| 	} claim_complete @0x200004; | 	} claim_complete @0x200004; | ||||||
| }; | }; | ||||||
							
								
								
									
										41
									
								
								riscv.sc/gen_input/prci.rdl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								riscv.sc/gen_input/prci.rdl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | |||||||
|  | regfile prci_regs { | ||||||
|  | 	reg { | ||||||
|  | 		name ="hfrosccfg"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field {} hfroscdiv[5:0]; | ||||||
|  | 		field {} hfrosctrim[20:16]; | ||||||
|  | 		field {} hfroscen[30:30]; | ||||||
|  | 		field {} hfroscrdy[31:31]; | ||||||
|  | 	} hfrosccfg @0x00; | ||||||
|  | 	reg { | ||||||
|  | 		name ="hfxosccfg"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field {} hfxoscrdy[31:31]; | ||||||
|  | 		field {} hfxoscen[30:30]; | ||||||
|  | 	} hfxosccfg @0x04; | ||||||
|  |      reg { | ||||||
|  |         name ="pllcfg"; | ||||||
|  |         desc = ""; | ||||||
|  |         field {} pllr[2:0]; | ||||||
|  |         field {} pllf[9:4]; | ||||||
|  |         field {} pllq[11:10]; | ||||||
|  |         field {} pllsel[16:16]; | ||||||
|  |         field {} pllrefsel[17:17]; | ||||||
|  |         field {} pllbypass[18:18]; | ||||||
|  |         field {} plllock[31:31]; | ||||||
|  |     } pllcfg @0x08; | ||||||
|  | 	reg { | ||||||
|  | 		name ="plloutdiv"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	} plloutdiv  @0x0c; | ||||||
|  | 	reg { | ||||||
|  | 		name ="coreclkcfg"; | ||||||
|  | 		desc = ""; | ||||||
|  | 		field { | ||||||
|  | 			name="data"; | ||||||
|  | 		} data[31:0]; | ||||||
|  | 	} coreclkcfg @0x10; | ||||||
|  | }; | ||||||
| @@ -1,5 +1,4 @@ | |||||||
| regfile spi_regs { | regfile spi_regs { | ||||||
| 	lsb0; |  | ||||||
| 	reg { | 	reg { | ||||||
| 		name="sckdiv"; | 		name="sckdiv"; | ||||||
| 		desc="Serial clock divisor"; | 		desc="Serial clock divisor"; | ||||||
|   | |||||||
| @@ -1,80 +1,45 @@ | |||||||
| regfile uart_regs { | regfile uart_regs { | ||||||
| 	lsb0; |  | ||||||
| 	reg { | 	reg { | ||||||
| 		name="txdata"; | 		name="txdata"; | ||||||
| 		desc="Transmit data register"; | 		desc="Transmit data register"; | ||||||
| 		field { | 		field {} data[7:0]; | ||||||
| 			name ="data"; | 		field {} full[31:31]; | ||||||
| 		} data[7:0]; |  | ||||||
| 		field { |  | ||||||
| 			name ="full"; |  | ||||||
| 		} full[31:31]; |  | ||||||
| 	} txdata @0x00; | 	} txdata @0x00; | ||||||
| 	reg { | 	reg { | ||||||
| 		name="rxdata"; | 		name="rxdata"; | ||||||
| 		desc="Receive data register"; | 		desc="Receive data register"; | ||||||
| 		field { | 		field {} data[7:0]; | ||||||
| 			name ="data"; | 		field {} empty[31:31]; | ||||||
| 		} data[7:0]; |  | ||||||
| 		field { |  | ||||||
| 			name ="empty"; |  | ||||||
| 		} empty[31:31]; |  | ||||||
| 	}rxdata @0x04; | 	}rxdata @0x04; | ||||||
| 	reg { | 	reg { | ||||||
| 		name="txctrl"; | 		name="txctrl"; | ||||||
| 		desc="Transmit control register"; | 		desc="Transmit control register"; | ||||||
| 		field { | 		field {} txen[1]; | ||||||
| 			name ="txen"; | 		field {} nstop[1]; | ||||||
| 		} txen[1]; | 		field {} txcnt[18:16]; | ||||||
| 		field { |  | ||||||
| 			name ="nstop"; |  | ||||||
| 		} nstop[1]; |  | ||||||
| 		field { |  | ||||||
| 			name ="reserved"; |  | ||||||
| 		} reserved[14]; |  | ||||||
| 		field { |  | ||||||
| 			name ="txcnt"; |  | ||||||
| 		} txcnt[3]; |  | ||||||
| 	}txctrl @0x08; | 	}txctrl @0x08; | ||||||
| 	reg { | 	reg { | ||||||
| 		name="rxctrl"; | 		name="rxctrl"; | ||||||
| 		desc="Receive control register"; | 		desc="Receive control register"; | ||||||
| 		field { | 		field {} rxen[1]; | ||||||
| 			name ="rxen"; | 		field {} rxcnt[18:16]; | ||||||
| 		} rxen[1]; |  | ||||||
| 		field { |  | ||||||
| 			name ="reserved"; |  | ||||||
| 		} reserved[15]; |  | ||||||
| 		field { |  | ||||||
| 			name ="rxcnt"; |  | ||||||
| 		} rxcnt[3]; |  | ||||||
| 	}rxctrl @0x0C; | 	}rxctrl @0x0C; | ||||||
| 	reg { | 	reg { | ||||||
| 		name="ie"; | 		name="ie"; | ||||||
| 		desc="UART interrupt enable"; | 		desc="UART interrupt enable"; | ||||||
| 		field{ | 		field{} txwm[1]; | ||||||
| 			name ="txwm"; | 		field{} rxwm[1]; | ||||||
| 		} txwm[1]; |  | ||||||
| 		field{ |  | ||||||
| 			name ="rxwm"; |  | ||||||
| 		} rxwm[1]; |  | ||||||
| 	}ie @0x10; | 	}ie @0x10; | ||||||
| 	reg { | 	reg { | ||||||
| 		name="ip"; | 		name="ip"; | ||||||
| 		desc="UART Interrupt pending"; | 		desc="UART Interrupt pending"; | ||||||
| 		field{ | 		field{} txwm[1]; | ||||||
| 			name ="txwm"; | 		field{} rxwm[1]; | ||||||
| 		} txwm[1]; |  | ||||||
| 		field{ |  | ||||||
| 			name ="rxwm"; |  | ||||||
| 		} rxwm[1]; |  | ||||||
| 	} ip @0x14; | 	} ip @0x14; | ||||||
| 	reg { | 	reg { | ||||||
| 		name="div"; | 		name="div"; | ||||||
| 		desc="Baud rate divisor"; | 		desc="Baud rate divisor"; | ||||||
| 		field{ | 		field{} div[16]; | ||||||
| 			name ="div"; |  | ||||||
| 		} div[16]; |  | ||||||
| 	} div @0x18; | 	} div @0x18; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,173 +0,0 @@ | |||||||
| /******************************************************************************* |  | ||||||
|  * Copyright (C) 2017, MINRES Technologies GmbH |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions are met: |  | ||||||
|  * |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright notice, |  | ||||||
|  *    this list of conditions and the following disclaimer. |  | ||||||
|  * |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, |  | ||||||
|  *    this list of conditions and the following disclaimer in the documentation |  | ||||||
|  *    and/or other materials provided with the distribution. |  | ||||||
|  * |  | ||||||
|  * 3. Neither the name of the copyright holder nor the names of its contributors |  | ||||||
|  *    may be used to endorse or promote products derived from this software |  | ||||||
|  *    without specific prior written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |  | ||||||
|  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |  | ||||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |  | ||||||
|  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |  | ||||||
|  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |  | ||||||
|  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |  | ||||||
|  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |  | ||||||
|  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |  | ||||||
|  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |  | ||||||
|  * POSSIBILITY OF SUCH DAMAGE. |  | ||||||
|  * |  | ||||||
|  * Contributors: |  | ||||||
|  *       eyck@minres.com - initial API and implementation |  | ||||||
|  ******************************************************************************/ |  | ||||||
|  |  | ||||||
| #ifndef _CLI_OPTIONS_H_ |  | ||||||
| #define _CLI_OPTIONS_H_ |  | ||||||
| #include <boost/program_options.hpp> |  | ||||||
| #include <cstdio> |  | ||||||
| #include <iostream> |  | ||||||
| #include <util/logging.h> |  | ||||||
|  |  | ||||||
| namespace { |  | ||||||
| const size_t ERROR_IN_COMMAND_LINE = 1; |  | ||||||
| const size_t SUCCESS = 0; |  | ||||||
| const size_t ERROR_UNHANDLED_EXCEPTION = 2; |  | ||||||
|  |  | ||||||
| inline void enable_log_level(int level) { |  | ||||||
|     switch (level) { |  | ||||||
|     case 0: |  | ||||||
|         logging::Logger::reporting_level() = logging::FATAL; |  | ||||||
|     /* no break */ |  | ||||||
|     case 1: |  | ||||||
|         logging::Logger::reporting_level() = logging::ERROR; |  | ||||||
|     /* no break */ |  | ||||||
|     case 2: |  | ||||||
|         logging::Logger::reporting_level() = logging::WARNING; |  | ||||||
|     /* no break */ |  | ||||||
|     case 3: |  | ||||||
|         logging::Logger::reporting_level() = logging::INFO; |  | ||||||
|     /* no break */ |  | ||||||
|     case 4: |  | ||||||
|         logging::Logger::reporting_level() = logging::DEBUG; |  | ||||||
|     /* no break */ |  | ||||||
|     case 5: |  | ||||||
|         logging::Logger::reporting_level() = logging::TRACE; |  | ||||||
|         /* no break */ |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| inline void configure_default_logger(boost::program_options::variables_map &vm) { |  | ||||||
|     //	el::Configurations defaultConf; |  | ||||||
|     //	defaultConf.setToDefault(); |  | ||||||
|     //	defaultConf.set(el::Level::Error, el::ConfigurationType::Format, |  | ||||||
|     //"%datetime{%H:%m:%s.%g} %level %msg"); |  | ||||||
|     //	defaultConf.set(el::Level::Warning, el::ConfigurationType::Format, |  | ||||||
|     //"%datetime{%H:%m:%s.%g} %level %msg"); |  | ||||||
|     //	defaultConf.set(el::Level::Info, el::ConfigurationType::Format, |  | ||||||
|     //"%datetime{%H:%m:%s.%g} %level %msg"); |  | ||||||
|     //	defaultConf.set(el::Level::Debug, el::ConfigurationType::Format, |  | ||||||
|     //"%datetime{%H:%m:%s.%g} %level %msg"); |  | ||||||
|     //	defaultConf.set(el::Level::Trace, el::ConfigurationType::Format, |  | ||||||
|     //"%datetime{%H:%m:%s.%g} %level %msg"); |  | ||||||
|     if (vm.count("verbose")) enable_log_level(vm["verbose"].as<int>()); |  | ||||||
|     if (vm.count("log-file")) logging::Output2FILE::stream() = fopen(vm["log-file"].as<std::string>().c_str(), "w"); |  | ||||||
|     // default logger uses default configurations |  | ||||||
|     //	el::Loggers::reconfigureLogger("default", defaultConf); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| inline void configure_debugger_logger() { |  | ||||||
|     // configure the connection logger |  | ||||||
|     //	el::Logger* gdbServerLogger = el::Loggers::getLogger(connection); |  | ||||||
|     //	el::Configurations gdbServerConf; |  | ||||||
|     //	gdbServerConf.setToDefault(); |  | ||||||
|     //	gdbServerConf.set(el::Level::Error, el::ConfigurationType::Format, |  | ||||||
|     //			"%datetime{%H:%m:%s.%g} %level [%logger] %msg"); |  | ||||||
|     //	gdbServerConf.set(el::Level::Warning, el::ConfigurationType::Format, |  | ||||||
|     //			"%datetime{%H:%m:%s.%g} %level [%logger] %msg"); |  | ||||||
|     //	gdbServerConf.set(el::Level::Info, el::ConfigurationType::Format, |  | ||||||
|     //			"%datetime{%H:%m:%s.%g} %level [%logger] %msg"); |  | ||||||
|     //	gdbServerConf.set(el::Level::Debug, el::ConfigurationType::Format, |  | ||||||
|     //			"%datetime{%H:%m:%s.%g} %level [%logger] %msg"); |  | ||||||
|     //	gdbServerConf.set(el::Level::Trace, el::ConfigurationType::Format, |  | ||||||
|     //			"%datetime{%H:%m:%s.%g} %level [%logger] %msg"); |  | ||||||
|     //	enable_log_level(gdbServerConf, 5); |  | ||||||
|     //	gdbServerLogger->configure(gdbServerConf); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| inline void configure_disass_logger(boost::program_options::variables_map &vm) { |  | ||||||
|     //    el::Logger* disassLogger = el::Loggers::getLogger(disass); |  | ||||||
|     //    el::Configurations disassConf; |  | ||||||
|     //    if(vm.count(disass)){ |  | ||||||
|     //        auto file_name=vm[disass].as<std::string>(); |  | ||||||
|     //        disassConf.setToDefault(); |  | ||||||
|     //        if (file_name.length() > 0) { |  | ||||||
|     //            disassConf.set(el::Level::Global, el::ConfigurationType::ToFile, |  | ||||||
|     //                    std::string("true")); |  | ||||||
|     //            disassConf.set(el::Level::Global, |  | ||||||
|     //                    el::ConfigurationType::ToStandardOutput, |  | ||||||
|     //                    std::string("false")); |  | ||||||
|     //            disassConf.set(el::Level::Global, el::ConfigurationType::Format, |  | ||||||
|     //                    std::string("%msg")); |  | ||||||
|     //            disassConf.set(el::Level::Global, |  | ||||||
|     //            el::ConfigurationType::Filename, |  | ||||||
|     //                    file_name); |  | ||||||
|     //            std::ofstream str(file_name); // just to clear the file |  | ||||||
|     //        } else { |  | ||||||
|     //            disassConf.set(el::Level::Global, el::ConfigurationType::Format, |  | ||||||
|     //                    "%datetime{%H:%m:%s.%g} [%logger] %msg"); |  | ||||||
|     //        } |  | ||||||
|     //    } else { |  | ||||||
|     //        enable_log_level(disassConf, 0); |  | ||||||
|     //    } |  | ||||||
|     //	disassLogger->configure(disassConf); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| } // namespace |  | ||||||
|  |  | ||||||
| inline int parse_cli_options(boost::program_options::variables_map &vm, int argc, char *argv[]) { |  | ||||||
|     namespace po = boost::program_options; |  | ||||||
|     po::options_description desc("Options"); |  | ||||||
|     desc.add_options()("help,h", "Print help message")("verbose,v", po::value<int>()->implicit_value(0), |  | ||||||
|                                                        "Sets logging verbosity")("vmodule", po::value<std::string>(), |  | ||||||
|                                                                                  "Defines the module(s) to be logged")( |  | ||||||
|         "logging-flags", po::value<int>(), "Sets logging flag(s).")("log-file", po::value<std::string>(), |  | ||||||
|                                                                     "Sets default log file.")( |  | ||||||
|         "disass,d", po::value<std::string>()->implicit_value(""), |  | ||||||
|         "Enables disassembly")("elf,l", po::value<std::vector<std::string>>(), "ELF file(s) to load")( |  | ||||||
|         "gdb-port,g", po::value<unsigned>(), "enable gdb server and specify port to use")( |  | ||||||
|         "input,i", po::value<std::string>(), "the elf file to load (instead of hex files)")( |  | ||||||
|         "dump-ir", "dump the intermediate representation")("cycles,c", po::value<int64_t>()->default_value(-1), |  | ||||||
|                                                            "number of cycles to run")( |  | ||||||
|         "systemc,s", "Run as SystemC simulation")("time", po::value<int>(), "SystemC siimulation time in ms")( |  | ||||||
|         "reset,r", po::value<std::string>(), "reset address")( |  | ||||||
|         "trace", po::value<uint8_t>(), "enable tracing, or cmbintation of 1=signals and 2=TX text, 4=TX " |  | ||||||
|                                        "compressed text, 6=TX in SQLite")("mem,m", po::value<std::string>(), |  | ||||||
|                                                                           "the memory input file")("rv64", "run RV64"); |  | ||||||
|     try { |  | ||||||
|         po::store(po::parse_command_line(argc, argv, desc), vm); // can throw |  | ||||||
|         // --help option |  | ||||||
|         if (vm.count("help")) { |  | ||||||
|             std::cout << "DBT-RISE-RiscV" << std::endl << desc << std::endl; |  | ||||||
|             return SUCCESS; |  | ||||||
|         } |  | ||||||
|         po::notify(vm); // throws on error, so do after help in case |  | ||||||
|     } catch (po::error &e) { |  | ||||||
|         // there are problems |  | ||||||
|         std::cerr << "ERROR: " << e.what() << std::endl << std::endl; |  | ||||||
|         std::cerr << desc << std::endl; |  | ||||||
|         return ERROR_IN_COMMAND_LINE; |  | ||||||
|     } |  | ||||||
|     return SUCCESS; |  | ||||||
| } |  | ||||||
| #endif /* _CLI_OPTIONS_H_ */ |  | ||||||
							
								
								
									
										43
									
								
								riscv.sc/incl/sysc/SiFive/aon.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								riscv.sc/incl/sysc/SiFive/aon.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  |  * Copyright 2017 eyck@minres.com | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||||||
|  |  * use this file except in compliance with the License.  You may obtain a copy | ||||||
|  |  * of the License at | ||||||
|  |  * | ||||||
|  |  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the | ||||||
|  |  * License for the specific language governing permissions and limitations under | ||||||
|  |  * the License. | ||||||
|  |  ******************************************************************************/ | ||||||
|  |  | ||||||
|  | #ifndef _AON_H_ | ||||||
|  | #define _AON_H_ | ||||||
|  |  | ||||||
|  | #include <sysc/tlm_target.h> | ||||||
|  |  | ||||||
|  | namespace sysc { | ||||||
|  |  | ||||||
|  | class aon_regs; | ||||||
|  |  | ||||||
|  | class aon : public sc_core::sc_module, public tlm_target<> { | ||||||
|  | public: | ||||||
|  |     SC_HAS_PROCESS(aon); | ||||||
|  |     sc_core::sc_in<sc_core::sc_time> clk_i; | ||||||
|  |     sc_core::sc_in<bool> rst_i; | ||||||
|  |     aon(sc_core::sc_module_name nm); | ||||||
|  |     virtual ~aon() override; // need to keep it in source file because of fwd declaration of aon_regs | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  |     void clock_cb(); | ||||||
|  |     void reset_cb(); | ||||||
|  |     sc_core::sc_time clk; | ||||||
|  |     std::unique_ptr<aon_regs> regs; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | } /* namespace sysc */ | ||||||
|  |  | ||||||
|  | #endif /* _GPIO_H_ */ | ||||||
							
								
								
									
										57
									
								
								riscv.sc/incl/sysc/SiFive/clint.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								riscv.sc/incl/sysc/SiFive/clint.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  |  * Copyright 2017 eyck@minres.com | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||||||
|  |  * use this file except in compliance with the License.  You may obtain a copy | ||||||
|  |  * of the License at | ||||||
|  |  * | ||||||
|  |  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the | ||||||
|  |  * License for the specific language governing permissions and limitations under | ||||||
|  |  * the License. | ||||||
|  |  ******************************************************************************/ | ||||||
|  |  | ||||||
|  | #ifndef _CLINT_H_ | ||||||
|  | #define _CLINT_H_ | ||||||
|  |  | ||||||
|  | #include <sysc/tlm_target.h> | ||||||
|  |  | ||||||
|  | namespace iss { | ||||||
|  | namespace arch { | ||||||
|  | template <typename BASE> struct riscv_hart_msu_vp; | ||||||
|  | } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | namespace sysc { | ||||||
|  |  | ||||||
|  | class clint_regs; | ||||||
|  | namespace SiFive { | ||||||
|  | class core_complex; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class clint : public sc_core::sc_module, public tlm_target<> { | ||||||
|  | public: | ||||||
|  |     SC_HAS_PROCESS(clint); | ||||||
|  |     sc_core::sc_in<sc_core::sc_time> clk_i; | ||||||
|  |     sc_core::sc_in<bool> rst_i; | ||||||
|  |     sc_core::sc_out<bool> mtime_int_o; | ||||||
|  |     sc_core::sc_out<bool> msip_int_o; | ||||||
|  |     clint(sc_core::sc_module_name nm); | ||||||
|  |     virtual ~clint() override; // need to keep it in source file because of fwd declaration of clint_regs | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  |     void clock_cb(); | ||||||
|  |     void reset_cb(); | ||||||
|  |     void update_mtime(); | ||||||
|  |     sc_core::sc_time clk, last_updt; | ||||||
|  |     unsigned cnt_fraction; | ||||||
|  |     std::unique_ptr<clint_regs> regs; | ||||||
|  |     sc_core::sc_event mtime_evt; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | } /* namespace sysc */ | ||||||
|  |  | ||||||
|  | #endif /* _CLINT_H_ */ | ||||||
| @@ -37,21 +37,89 @@ | |||||||
| #ifndef _SYSC_SIFIVE_FE310_H_ | #ifndef _SYSC_SIFIVE_FE310_H_ | ||||||
| #define _SYSC_SIFIVE_FE310_H_ | #define _SYSC_SIFIVE_FE310_H_ | ||||||
|  |  | ||||||
| #include <iss/arch/riscv_hart_msu_vp.h> | #include <sysc/ext_attribute.h> | ||||||
| #include <iss/arch/rv32imac.h> | #include <sysc/initiator_mixin.h> | ||||||
|  | #include <sysc/traceable.h> | ||||||
| #include <sysc/utilities.h> | #include <sysc/utilities.h> | ||||||
| #include <tlm> | #include <tlm> | ||||||
|  | #include <tlm_utils/tlm_quantumkeeper.h> | ||||||
|  | #include <util/range_lut.h> | ||||||
|  |  | ||||||
|  | namespace iss { | ||||||
|  | class vm_if; | ||||||
|  | namespace arch { | ||||||
|  | template <typename BASE> struct riscv_hart_msu_vp; | ||||||
|  | } | ||||||
|  | } | ||||||
|  |  | ||||||
| namespace sysc { | namespace sysc { | ||||||
| namespace SiFive { |  | ||||||
|  |  | ||||||
| class core_complex : public iss::arch::riscv_hart_msu_vp<iss::arch::rv32imac>, public sc_core::sc_module { | class tlm_dmi_ext : public tlm::tlm_dmi { | ||||||
| public: | public: | ||||||
|     tlm::tlm_initiator_socket<32> initiator; |     bool operator==(const tlm_dmi_ext &o) const { | ||||||
|  |         return this->get_granted_access() == o.get_granted_access() && | ||||||
|  |                this->get_start_address() == o.get_start_address() && this->get_end_address() == o.get_end_address(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     bool operator!=(const tlm_dmi_ext &o) const { return !operator==(o); } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | namespace SiFive { | ||||||
|  | class core_wrapper; | ||||||
|  |  | ||||||
|  | class core_complex : public sc_core::sc_module, public sysc::traceable { | ||||||
|  | public: | ||||||
|  |     SC_HAS_PROCESS(core_complex); | ||||||
|  |  | ||||||
|  |     sysc::initiator_mixin<tlm::tlm_initiator_socket<32>> initiator; | ||||||
|  |  | ||||||
|  |     sc_core::sc_in<sc_core::sc_time> clk_i; | ||||||
|  |  | ||||||
|     sc_core::sc_in<bool> rst_i; |     sc_core::sc_in<bool> rst_i; | ||||||
|  |  | ||||||
|  |     sysc::ext_attribute<std::string> elf_file; | ||||||
|  |  | ||||||
|  |     sysc::ext_attribute<bool> enable_disass; | ||||||
|  |  | ||||||
|  |     sysc::ext_attribute<uint64_t> reset_address; | ||||||
|  |  | ||||||
|  |     sysc::ext_attribute<unsigned short> gdb_server_port; | ||||||
|  |  | ||||||
|  |     sysc::ext_attribute<bool> dump_ir; | ||||||
|  |  | ||||||
|     core_complex(sc_core::sc_module_name name); |     core_complex(sc_core::sc_module_name name); | ||||||
|     virtual ~core_complex() = default; |  | ||||||
|  |     ~core_complex(); | ||||||
|  |  | ||||||
|  |     inline void sync() { | ||||||
|  |         quantum_keeper.inc(curr_clk); | ||||||
|  |         if (quantum_keeper.need_sync()) { | ||||||
|  |             wait(quantum_keeper.get_local_time()); | ||||||
|  |             quantum_keeper.reset(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     bool read_mem(uint64_t addr, unsigned length, uint8_t *const data); | ||||||
|  |  | ||||||
|  |     bool write_mem(uint64_t addr, unsigned length, const uint8_t *const data); | ||||||
|  |  | ||||||
|  |     bool read_mem_dbg(uint64_t addr, unsigned length, uint8_t *const data); | ||||||
|  |  | ||||||
|  |     bool write_mem_dbg(uint64_t addr, unsigned length, const uint8_t *const data); | ||||||
|  |  | ||||||
|  |     void trace(sc_core::sc_trace_file *trf) override; | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  |     void before_end_of_elaboration(); | ||||||
|  |     void start_of_simulation(); | ||||||
|  |     void run(); | ||||||
|  |     void clk_cb(); | ||||||
|  |     util::range_lut<tlm_dmi_ext> read_lut, write_lut; | ||||||
|  |     tlm_utils::tlm_quantumkeeper quantum_keeper; | ||||||
|  |     std::vector<uint8_t> write_buf; | ||||||
|  |     std::unique_ptr<core_wrapper> cpu; | ||||||
|  |     std::unique_ptr<iss::vm_if> vm; | ||||||
|  |     sc_core::sc_time curr_clk; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } /* namespace SiFive */ | } /* namespace SiFive */ | ||||||
|   | |||||||
							
								
								
									
										173
									
								
								riscv.sc/incl/sysc/SiFive/gen/aon_regs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								riscv.sc/incl/sysc/SiFive/gen/aon_regs.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,173 @@ | |||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | // Copyright (C) 2017, MINRES Technologies GmbH | ||||||
|  | // All rights reserved. | ||||||
|  | // | ||||||
|  | // Redistribution and use in source and binary forms, with or without | ||||||
|  | // modification, are permitted provided that the following conditions are met: | ||||||
|  | // | ||||||
|  | // 1. Redistributions of source code must retain the above copyright notice, | ||||||
|  | //    this list of conditions and the following disclaimer. | ||||||
|  | // | ||||||
|  | // 2. Redistributions in binary form must reproduce the above copyright notice, | ||||||
|  | //    this list of conditions and the following disclaimer in the documentation | ||||||
|  | //    and/or other materials provided with the distribution. | ||||||
|  | // | ||||||
|  | // 3. Neither the name of the copyright holder nor the names of its contributors | ||||||
|  | //    may be used to endorse or promote products derived from this software | ||||||
|  | //    without specific prior written permission. | ||||||
|  | // | ||||||
|  | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||||
|  | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||||
|  | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||||
|  | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||||||
|  | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||||||
|  | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||||||
|  | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||||||
|  | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||||||
|  | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||||||
|  | // 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 | ||||||
|  | //             *      aon_regs.h Author: <RDL Generator> | ||||||
|  | // | ||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | #ifndef _AON_REGS_H_ | ||||||
|  | #define _AON_REGS_H_ | ||||||
|  |  | ||||||
|  | #include <sysc/register.h> | ||||||
|  | #include <sysc/tlm_target.h> | ||||||
|  | #include <sysc/utilities.h> | ||||||
|  | #include <util/bit_field.h> | ||||||
|  |  | ||||||
|  | namespace sysc { | ||||||
|  |  | ||||||
|  | class aon_regs : public sc_core::sc_module, public sysc::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(); | ||||||
|  |     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(); | ||||||
|  |     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 | ||||||
|  |     sysc::sc_register<uint32_t> wdogcfg; | ||||||
|  |     sysc::sc_register<uint32_t> wdogcount; | ||||||
|  |     sysc::sc_register<uint32_t> wdogs; | ||||||
|  |     sysc::sc_register<uint32_t> wdogfeed; | ||||||
|  |     sysc::sc_register<uint32_t> wdogkey; | ||||||
|  |     sysc::sc_register<uint32_t> wdogcmp; | ||||||
|  |     sysc::sc_register<uint32_t> rtccfg; | ||||||
|  |     sysc::sc_register<uint32_t> rtclo; | ||||||
|  |     sysc::sc_register<uint32_t> rtchi; | ||||||
|  |     sysc::sc_register<uint32_t> rtcs; | ||||||
|  |     sysc::sc_register<uint32_t> rtccmp; | ||||||
|  |     sysc::sc_register<uint32_t> lfrosccfg; | ||||||
|  |     sysc::sc_register_indexed<uint32_t, 32> backup; | ||||||
|  |     sysc::sc_register_indexed<pmuwakeupi_t, 8> pmuwakeupi; | ||||||
|  |     sysc::sc_register_indexed<pmusleepi_t, 8> pmusleepi; | ||||||
|  |     sysc::sc_register<uint32_t> pmuie; | ||||||
|  |     sysc::sc_register<uint32_t> pmucause; | ||||||
|  |     sysc::sc_register<uint32_t> pmusleep; | ||||||
|  |     sysc::sc_register<uint32_t> pmukey; | ||||||
|  |  | ||||||
|  |     aon_regs(sc_core::sc_module_name nm); | ||||||
|  |  | ||||||
|  |     template <unsigned BUSWIDTH = 32> void registerResources(sysc::tlm_target<BUSWIDTH> &target); | ||||||
|  | }; | ||||||
|  | } | ||||||
|  | ////////////////////////////////////////////////////////////////////////////// | ||||||
|  | // member functions | ||||||
|  | ////////////////////////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | inline sysc::aon_regs::aon_regs(sc_core::sc_module_name nm) | ||||||
|  | : sc_core::sc_module(nm) | ||||||
|  | , NAMED(wdogcfg, r_wdogcfg, 0, *this) | ||||||
|  | , NAMED(wdogcount, r_wdogcount, 0, *this) | ||||||
|  | , NAMED(wdogs, r_wdogs, 0, *this) | ||||||
|  | , NAMED(wdogfeed, r_wdogfeed, 0, *this) | ||||||
|  | , NAMED(wdogkey, r_wdogkey, 0, *this) | ||||||
|  | , NAMED(wdogcmp, r_wdogcmp, 0, *this) | ||||||
|  | , NAMED(rtccfg, r_rtccfg, 0, *this) | ||||||
|  | , NAMED(rtclo, r_rtclo, 0, *this) | ||||||
|  | , NAMED(rtchi, r_rtchi, 0, *this) | ||||||
|  | , NAMED(rtcs, r_rtcs, 0, *this) | ||||||
|  | , NAMED(rtccmp, r_rtccmp, 0, *this) | ||||||
|  | , NAMED(lfrosccfg, r_lfrosccfg, 0, *this) | ||||||
|  | , NAMED(backup, r_backup, 0, *this) | ||||||
|  | , NAMED(pmuwakeupi, r_pmuwakeupi, 0, *this) | ||||||
|  | , NAMED(pmusleepi, r_pmusleepi, 0, *this) | ||||||
|  | , NAMED(pmuie, r_pmuie, 0, *this) | ||||||
|  | , NAMED(pmucause, r_pmucause, 0, *this) | ||||||
|  | , NAMED(pmusleep, r_pmusleep, 0, *this) | ||||||
|  | , NAMED(pmukey, r_pmukey, 0, *this) {} | ||||||
|  |  | ||||||
|  | template <unsigned BUSWIDTH> inline void sysc::aon_regs::registerResources(sysc::tlm_target<BUSWIDTH> &target) { | ||||||
|  |     target.addResource(wdogcfg, 0x0UL); | ||||||
|  |     target.addResource(wdogcount, 0x8UL); | ||||||
|  |     target.addResource(wdogs, 0x10UL); | ||||||
|  |     target.addResource(wdogfeed, 0x18UL); | ||||||
|  |     target.addResource(wdogkey, 0x1cUL); | ||||||
|  |     target.addResource(wdogcmp, 0x20UL); | ||||||
|  |     target.addResource(rtccfg, 0x40UL); | ||||||
|  |     target.addResource(rtclo, 0x48UL); | ||||||
|  |     target.addResource(rtchi, 0x4cUL); | ||||||
|  |     target.addResource(rtcs, 0x50UL); | ||||||
|  |     target.addResource(rtccmp, 0x60UL); | ||||||
|  |     target.addResource(lfrosccfg, 0x70UL); | ||||||
|  |     target.addResource(backup, 0x80UL); | ||||||
|  |     target.addResource(pmuwakeupi, 0x100UL); | ||||||
|  |     target.addResource(pmusleepi, 0x120UL); | ||||||
|  |     target.addResource(pmuie, 0x140UL); | ||||||
|  |     target.addResource(pmucause, 0x144UL); | ||||||
|  |     target.addResource(pmusleep, 0x148UL); | ||||||
|  |     target.addResource(pmukey, 0x14cUL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif // _AON_REGS_H_ | ||||||
							
								
								
									
										83
									
								
								riscv.sc/incl/sysc/SiFive/gen/clint_regs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								riscv.sc/incl/sysc/SiFive/gen/clint_regs.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | |||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | // Copyright (C) 2017, MINRES Technologies GmbH | ||||||
|  | // All rights reserved. | ||||||
|  | // | ||||||
|  | // Redistribution and use in source and binary forms, with or without | ||||||
|  | // modification, are permitted provided that the following conditions are met: | ||||||
|  | // | ||||||
|  | // 1. Redistributions of source code must retain the above copyright notice, | ||||||
|  | //    this list of conditions and the following disclaimer. | ||||||
|  | // | ||||||
|  | // 2. Redistributions in binary form must reproduce the above copyright notice, | ||||||
|  | //    this list of conditions and the following disclaimer in the documentation | ||||||
|  | //    and/or other materials provided with the distribution. | ||||||
|  | // | ||||||
|  | // 3. Neither the name of the copyright holder nor the names of its contributors | ||||||
|  | //    may be used to endorse or promote products derived from this software | ||||||
|  | //    without specific prior written permission. | ||||||
|  | // | ||||||
|  | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||||
|  | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||||
|  | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||||
|  | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||||||
|  | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||||||
|  | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||||||
|  | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||||||
|  | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||||||
|  | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||||||
|  | // 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 | ||||||
|  | //             *      clint_regs.h Author: <RDL Generator> | ||||||
|  | // | ||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | #ifndef _CLINT_REGS_H_ | ||||||
|  | #define _CLINT_REGS_H_ | ||||||
|  |  | ||||||
|  | #include <sysc/register.h> | ||||||
|  | #include <sysc/tlm_target.h> | ||||||
|  | #include <sysc/utilities.h> | ||||||
|  | #include <util/bit_field.h> | ||||||
|  |  | ||||||
|  | namespace sysc { | ||||||
|  |  | ||||||
|  | class clint_regs : public sc_core::sc_module, public sysc::resetable { | ||||||
|  | public: | ||||||
|  |     // storage declarations | ||||||
|  |     BEGIN_BF_DECL(msip_t, uint32_t); | ||||||
|  |     BF_FIELD(msip, 0, 1); | ||||||
|  |     END_BF_DECL() r_msip; | ||||||
|  |  | ||||||
|  |     uint64_t r_mtimecmp; | ||||||
|  |  | ||||||
|  |     uint64_t r_mtime; | ||||||
|  |  | ||||||
|  |     // register declarations | ||||||
|  |     sysc::sc_register<msip_t> msip; | ||||||
|  |     sysc::sc_register<uint64_t> mtimecmp; | ||||||
|  |     sysc::sc_register<uint64_t> mtime; | ||||||
|  |  | ||||||
|  |     clint_regs(sc_core::sc_module_name nm); | ||||||
|  |  | ||||||
|  |     template <unsigned BUSWIDTH = 32> void registerResources(sysc::tlm_target<BUSWIDTH> &target); | ||||||
|  | }; | ||||||
|  | } | ||||||
|  | ////////////////////////////////////////////////////////////////////////////// | ||||||
|  | // member functions | ||||||
|  | ////////////////////////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | 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) {} | ||||||
|  |  | ||||||
|  | template <unsigned BUSWIDTH> inline void sysc::clint_regs::registerResources(sysc::tlm_target<BUSWIDTH> &target) { | ||||||
|  |     target.addResource(msip, 0x0UL); | ||||||
|  |     target.addResource(mtimecmp, 0x4000UL); | ||||||
|  |     target.addResource(mtime, 0xbff8UL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif // _CLINT_REGS_H_ | ||||||
| @@ -2,11 +2,15 @@ | |||||||
| #define _E300_PLAT_MAP_H_ | #define _E300_PLAT_MAP_H_ | ||||||
| // need double braces, see | // need double braces, see | ||||||
| // https://stackoverflow.com/questions/6893700/how-to-construct-stdarray-object-with-initializer-list#6894191 | // https://stackoverflow.com/questions/6893700/how-to-construct-stdarray-object-with-initializer-list#6894191 | ||||||
| const std::array<sysc::target_memory_map_entry<32>, 4> e300_plat_map = {{ | const std::array<sysc::target_memory_map_entry<32>, 8> e300_plat_map = {{ | ||||||
|     {&i_plic, 0xc000000, 0x1000}, |     {&i_clint, 0x2000000, 0xc000}, | ||||||
|     {&i_gpio, 0x10012000, 0x1000}, |     {&i_plic, 0xc000000, 0x200008}, | ||||||
|     {&i_uart, 0x10013000, 0x1000}, |     {&i_aon, 0x10000000, 0x150}, | ||||||
|     {&i_spi, 0x10014000, 0x1000}, |     {&i_prci, 0x10008000, 0x14}, | ||||||
|  |     {&i_gpio, 0x10012000, 0x44}, | ||||||
|  |     {&i_uart0, 0x10013000, 0x1c}, | ||||||
|  |     {&i_uart1, 0x10023000, 0x1c}, | ||||||
|  |     {&i_spi, 0x10014000, 0x78}, | ||||||
| }}; | }}; | ||||||
|  |  | ||||||
| #endif /* _E300_PLAT_MAP_H_ */ | #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 | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||||
| // POSSIBILITY OF SUCH DAMAGE. | // POSSIBILITY OF SUCH DAMAGE. | ||||||
| // | // | ||||||
| // Created on: Wed Sep 20 11:47:24 CEST 2017 | // Created on: Wed Oct 04 10:06:35 CEST 2017 | ||||||
| //             *      gpio_regs.h Author: <RDL Generator> | //             *      gpio_regs.h Author: <RDL Generator> | ||||||
| // | // | ||||||
| //////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||||||
| @@ -44,7 +44,7 @@ | |||||||
| namespace sysc { | namespace sysc { | ||||||
|  |  | ||||||
| class gpio_regs : public sc_core::sc_module, public sysc::resetable { | class gpio_regs : public sc_core::sc_module, public sysc::resetable { | ||||||
| protected: | public: | ||||||
|     // storage declarations |     // storage declarations | ||||||
|     uint32_t r_value; |     uint32_t r_value; | ||||||
|  |  | ||||||
| @@ -99,7 +99,6 @@ protected: | |||||||
|     sysc::sc_register<uint32_t> iof_sel; |     sysc::sc_register<uint32_t> iof_sel; | ||||||
|     sysc::sc_register<uint32_t> out_xor; |     sysc::sc_register<uint32_t> out_xor; | ||||||
|  |  | ||||||
| public: |  | ||||||
|     gpio_regs(sc_core::sc_module_name nm); |     gpio_regs(sc_core::sc_module_name nm); | ||||||
|  |  | ||||||
|     template <unsigned BUSWIDTH = 32> void registerResources(sysc::tlm_target<BUSWIDTH> &target); |     template <unsigned BUSWIDTH = 32> void registerResources(sysc::tlm_target<BUSWIDTH> &target); | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ | |||||||
| // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||||
| // POSSIBILITY OF SUCH DAMAGE. | // POSSIBILITY OF SUCH DAMAGE. | ||||||
| // | // | ||||||
| // Created on: Wed Sep 20 22:30:45 CEST 2017 | // Created on: Wed Oct 04 10:06:35 CEST 2017 | ||||||
| //             *      plic_regs.h Author: <RDL Generator> | //             *      plic_regs.h Author: <RDL Generator> | ||||||
| // | // | ||||||
| //////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||||||
| @@ -44,7 +44,7 @@ | |||||||
| namespace sysc { | namespace sysc { | ||||||
|  |  | ||||||
| class plic_regs : public sc_core::sc_module, public sysc::resetable { | class plic_regs : public sc_core::sc_module, public sysc::resetable { | ||||||
| protected: | public: | ||||||
|     // storage declarations |     // storage declarations | ||||||
|     BEGIN_BF_DECL(priority_t, uint32_t); |     BEGIN_BF_DECL(priority_t, uint32_t); | ||||||
|     BF_FIELD(priority, 0, 3); |     BF_FIELD(priority, 0, 3); | ||||||
| @@ -68,7 +68,6 @@ protected: | |||||||
|     sysc::sc_register<threshold_t> threshold; |     sysc::sc_register<threshold_t> threshold; | ||||||
|     sysc::sc_register<uint32_t> claim_complete; |     sysc::sc_register<uint32_t> claim_complete; | ||||||
|  |  | ||||||
| public: |  | ||||||
|     plic_regs(sc_core::sc_module_name nm); |     plic_regs(sc_core::sc_module_name nm); | ||||||
|  |  | ||||||
|     template <unsigned BUSWIDTH = 32> void registerResources(sysc::tlm_target<BUSWIDTH> &target); |     template <unsigned BUSWIDTH = 32> void registerResources(sysc::tlm_target<BUSWIDTH> &target); | ||||||
| @@ -90,8 +89,8 @@ template <unsigned BUSWIDTH> inline void sysc::plic_regs::registerResources(sysc | |||||||
|     target.addResource(priority, 0x4UL); |     target.addResource(priority, 0x4UL); | ||||||
|     target.addResource(pending, 0x1000UL); |     target.addResource(pending, 0x1000UL); | ||||||
|     target.addResource(enabled, 0x2000UL); |     target.addResource(enabled, 0x2000UL); | ||||||
|     target.addResource(threshold, 0xc200000UL); |     target.addResource(threshold, 0x200000UL); | ||||||
|     target.addResource(claim_complete, 0xc200004UL); |     target.addResource(claim_complete, 0x200004UL); | ||||||
| } | } | ||||||
|  |  | ||||||
| #endif // _PLIC_REGS_H_ | #endif // _PLIC_REGS_H_ | ||||||
|   | |||||||
							
								
								
									
										107
									
								
								riscv.sc/incl/sysc/SiFive/gen/prci_regs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								riscv.sc/incl/sysc/SiFive/gen/prci_regs.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,107 @@ | |||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | // Copyright (C) 2017, MINRES Technologies GmbH | ||||||
|  | // All rights reserved. | ||||||
|  | // | ||||||
|  | // Redistribution and use in source and binary forms, with or without | ||||||
|  | // modification, are permitted provided that the following conditions are met: | ||||||
|  | // | ||||||
|  | // 1. Redistributions of source code must retain the above copyright notice, | ||||||
|  | //    this list of conditions and the following disclaimer. | ||||||
|  | // | ||||||
|  | // 2. Redistributions in binary form must reproduce the above copyright notice, | ||||||
|  | //    this list of conditions and the following disclaimer in the documentation | ||||||
|  | //    and/or other materials provided with the distribution. | ||||||
|  | // | ||||||
|  | // 3. Neither the name of the copyright holder nor the names of its contributors | ||||||
|  | //    may be used to endorse or promote products derived from this software | ||||||
|  | //    without specific prior written permission. | ||||||
|  | // | ||||||
|  | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||||
|  | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||||
|  | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||||
|  | // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||||||
|  | // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||||||
|  | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||||||
|  | // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||||||
|  | // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||||||
|  | // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||||||
|  | // 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 | ||||||
|  | //             *      prci_regs.h Author: <RDL Generator> | ||||||
|  | // | ||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | #ifndef _PRCI_REGS_H_ | ||||||
|  | #define _PRCI_REGS_H_ | ||||||
|  |  | ||||||
|  | #include <sysc/register.h> | ||||||
|  | #include <sysc/tlm_target.h> | ||||||
|  | #include <sysc/utilities.h> | ||||||
|  | #include <util/bit_field.h> | ||||||
|  |  | ||||||
|  | namespace sysc { | ||||||
|  |  | ||||||
|  | class prci_regs : public sc_core::sc_module, public sysc::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); | ||||||
|  |     END_BF_DECL() r_hfrosccfg; | ||||||
|  |  | ||||||
|  |     BEGIN_BF_DECL(hfxosccfg_t, uint32_t); | ||||||
|  |     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); | ||||||
|  |     END_BF_DECL() r_pllcfg; | ||||||
|  |  | ||||||
|  |     uint32_t r_plloutdiv; | ||||||
|  |  | ||||||
|  |     uint32_t r_coreclkcfg; | ||||||
|  |  | ||||||
|  |     // register declarations | ||||||
|  |     sysc::sc_register<hfrosccfg_t> hfrosccfg; | ||||||
|  |     sysc::sc_register<hfxosccfg_t> hfxosccfg; | ||||||
|  |     sysc::sc_register<pllcfg_t> pllcfg; | ||||||
|  |     sysc::sc_register<uint32_t> plloutdiv; | ||||||
|  |     sysc::sc_register<uint32_t> coreclkcfg; | ||||||
|  |  | ||||||
|  |     prci_regs(sc_core::sc_module_name nm); | ||||||
|  |  | ||||||
|  |     template <unsigned BUSWIDTH = 32> void registerResources(sysc::tlm_target<BUSWIDTH> &target); | ||||||
|  | }; | ||||||
|  | } | ||||||
|  | ////////////////////////////////////////////////////////////////////////////// | ||||||
|  | // member functions | ||||||
|  | ////////////////////////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | inline sysc::prci_regs::prci_regs(sc_core::sc_module_name nm) | ||||||
|  | : sc_core::sc_module(nm) | ||||||
|  | , NAMED(hfrosccfg, r_hfrosccfg, 0, *this) | ||||||
|  | , NAMED(hfxosccfg, r_hfxosccfg, 0, *this) | ||||||
|  | , NAMED(pllcfg, r_pllcfg, 0, *this) | ||||||
|  | , NAMED(plloutdiv, r_plloutdiv, 0, *this) | ||||||
|  | , NAMED(coreclkcfg, r_coreclkcfg, 0, *this) {} | ||||||
|  |  | ||||||
|  | template <unsigned BUSWIDTH> inline void sysc::prci_regs::registerResources(sysc::tlm_target<BUSWIDTH> &target) { | ||||||
|  |     target.addResource(hfrosccfg, 0x0UL); | ||||||
|  |     target.addResource(hfxosccfg, 0x4UL); | ||||||
|  |     target.addResource(pllcfg, 0x8UL); | ||||||
|  |     target.addResource(plloutdiv, 0xcUL); | ||||||
|  |     target.addResource(coreclkcfg, 0x10UL); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif // _PRCI_REGS_H_ | ||||||
| @@ -28,7 +28,7 @@ | |||||||
| // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||||
| // POSSIBILITY OF SUCH DAMAGE. | // POSSIBILITY OF SUCH DAMAGE. | ||||||
| // | // | ||||||
| // Created on: Wed Sep 20 22:30:45 CEST 2017 | // Created on: Wed Oct 04 10:06:35 CEST 2017 | ||||||
| //             *      spi_regs.h Author: <RDL Generator> | //             *      spi_regs.h Author: <RDL Generator> | ||||||
| // | // | ||||||
| //////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||||||
| @@ -44,7 +44,7 @@ | |||||||
| namespace sysc { | namespace sysc { | ||||||
|  |  | ||||||
| class spi_regs : public sc_core::sc_module, public sysc::resetable { | class spi_regs : public sc_core::sc_module, public sysc::resetable { | ||||||
| protected: | public: | ||||||
|     // storage declarations |     // storage declarations | ||||||
|     BEGIN_BF_DECL(sckdiv_t, uint32_t); |     BEGIN_BF_DECL(sckdiv_t, uint32_t); | ||||||
|     BF_FIELD(div, 0, 12); |     BF_FIELD(div, 0, 12); | ||||||
| @@ -141,7 +141,6 @@ protected: | |||||||
|     sysc::sc_register<ie_t> ie; |     sysc::sc_register<ie_t> ie; | ||||||
|     sysc::sc_register<ip_t> ip; |     sysc::sc_register<ip_t> ip; | ||||||
|  |  | ||||||
| public: |  | ||||||
|     spi_regs(sc_core::sc_module_name nm); |     spi_regs(sc_core::sc_module_name nm); | ||||||
|  |  | ||||||
|     template <unsigned BUSWIDTH = 32> void registerResources(sysc::tlm_target<BUSWIDTH> &target); |     template <unsigned BUSWIDTH = 32> void registerResources(sysc::tlm_target<BUSWIDTH> &target); | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ | |||||||
| // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||||
| // POSSIBILITY OF SUCH DAMAGE. | // POSSIBILITY OF SUCH DAMAGE. | ||||||
| // | // | ||||||
| // Created on: Wed Sep 20 22:30:45 CEST 2017 | // Created on: Wed Oct 04 10:06:35 CEST 2017 | ||||||
| //             *      uart_regs.h Author: <RDL Generator> | //             *      uart_regs.h Author: <RDL Generator> | ||||||
| // | // | ||||||
| //////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||||||
| @@ -44,7 +44,7 @@ | |||||||
| namespace sysc { | namespace sysc { | ||||||
|  |  | ||||||
| class uart_regs : public sc_core::sc_module, public sysc::resetable { | class uart_regs : public sc_core::sc_module, public sysc::resetable { | ||||||
| protected: | public: | ||||||
|     // storage declarations |     // storage declarations | ||||||
|     BEGIN_BF_DECL(txdata_t, uint32_t); |     BEGIN_BF_DECL(txdata_t, uint32_t); | ||||||
|     BF_FIELD(data, 0, 8); |     BF_FIELD(data, 0, 8); | ||||||
| @@ -59,13 +59,11 @@ protected: | |||||||
|     BEGIN_BF_DECL(txctrl_t, uint32_t); |     BEGIN_BF_DECL(txctrl_t, uint32_t); | ||||||
|     BF_FIELD(txen, 0, 1); |     BF_FIELD(txen, 0, 1); | ||||||
|     BF_FIELD(nstop, 1, 1); |     BF_FIELD(nstop, 1, 1); | ||||||
|     BF_FIELD(reserved, 2, 14); |  | ||||||
|     BF_FIELD(txcnt, 16, 3); |     BF_FIELD(txcnt, 16, 3); | ||||||
|     END_BF_DECL() r_txctrl; |     END_BF_DECL() r_txctrl; | ||||||
|  |  | ||||||
|     BEGIN_BF_DECL(rxctrl_t, uint32_t); |     BEGIN_BF_DECL(rxctrl_t, uint32_t); | ||||||
|     BF_FIELD(rxen, 0, 1); |     BF_FIELD(rxen, 0, 1); | ||||||
|     BF_FIELD(reserved, 1, 15); |  | ||||||
|     BF_FIELD(rxcnt, 16, 3); |     BF_FIELD(rxcnt, 16, 3); | ||||||
|     END_BF_DECL() r_rxctrl; |     END_BF_DECL() r_rxctrl; | ||||||
|  |  | ||||||
| @@ -92,7 +90,6 @@ protected: | |||||||
|     sysc::sc_register<ip_t> ip; |     sysc::sc_register<ip_t> ip; | ||||||
|     sysc::sc_register<div_t> div; |     sysc::sc_register<div_t> div; | ||||||
|  |  | ||||||
| public: |  | ||||||
|     uart_regs(sc_core::sc_module_name nm); |     uart_regs(sc_core::sc_module_name nm); | ||||||
|  |  | ||||||
|     template <unsigned BUSWIDTH = 32> void registerResources(sysc::tlm_target<BUSWIDTH> &target); |     template <unsigned BUSWIDTH = 32> void registerResources(sysc::tlm_target<BUSWIDTH> &target); | ||||||
|   | |||||||
| @@ -23,14 +23,19 @@ | |||||||
| #ifndef SIMPLESYSTEM_H_ | #ifndef SIMPLESYSTEM_H_ | ||||||
| #define SIMPLESYSTEM_H_ | #define SIMPLESYSTEM_H_ | ||||||
|  |  | ||||||
|  | #include "aon.h" | ||||||
|  | #include "clint.h" | ||||||
| #include "gpio.h" | #include "gpio.h" | ||||||
| #include "plic.h" | #include "plic.h" | ||||||
|  | #include "prci.h" | ||||||
| #include "spi.h" | #include "spi.h" | ||||||
| #include "uart.h" | #include "uart.h" | ||||||
|  |  | ||||||
| #include <array> | #include <array> | ||||||
| #include <sysc/kernel/sc_module.h> | #include <sysc/kernel/sc_module.h> | ||||||
|  | #include <sysc/memory.h> | ||||||
| #include <sysc/router.h> | #include <sysc/router.h> | ||||||
|  | #include <sysc/utilities.h> | ||||||
|  |  | ||||||
| #include "core_complex.h" | #include "core_complex.h" | ||||||
|  |  | ||||||
| @@ -40,14 +45,20 @@ class platform : public sc_core::sc_module { | |||||||
| public: | public: | ||||||
|     SC_HAS_PROCESS(platform); |     SC_HAS_PROCESS(platform); | ||||||
|  |  | ||||||
|     SiFive::core_complex i_master; |     SiFive::core_complex i_core_complex; | ||||||
|     router<> i_router; |     router<> i_router; | ||||||
|     uart i_uart; |     uart i_uart0, i_uart1; | ||||||
|     spi i_spi; |     spi i_spi; | ||||||
|     gpio i_gpio; |     gpio i_gpio; | ||||||
|     plic i_plic; |     plic i_plic; | ||||||
|  |     aon i_aon; | ||||||
|  |     prci i_prci; | ||||||
|  |     clint i_clint; | ||||||
|  |  | ||||||
|  |     memory<512_MB, 32> i_mem_qspi; | ||||||
|  |     memory<128_kB, 32> i_mem_ram; | ||||||
|     sc_core::sc_signal<sc_core::sc_time> s_clk; |     sc_core::sc_signal<sc_core::sc_time> s_clk; | ||||||
|     sc_core::sc_signal<bool> s_rst; |     sc_core::sc_signal<bool> s_rst, s_mtime_int, s_msie_int; | ||||||
|  |  | ||||||
|     platform(sc_core::sc_module_name nm); |     platform(sc_core::sc_module_name nm); | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										45
									
								
								riscv.sc/incl/sysc/SiFive/prci.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								riscv.sc/incl/sysc/SiFive/prci.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | |||||||
|  | /******************************************************************************* | ||||||
|  |  * Copyright 2017 eyck@minres.com | ||||||
|  |  * | ||||||
|  |  * Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||||||
|  |  * use this file except in compliance with the License.  You may obtain a copy | ||||||
|  |  * of the License at | ||||||
|  |  * | ||||||
|  |  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  |  * | ||||||
|  |  * Unless required by applicable law or agreed to in writing, software | ||||||
|  |  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||||
|  |  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the | ||||||
|  |  * License for the specific language governing permissions and limitations under | ||||||
|  |  * the License. | ||||||
|  |  ******************************************************************************/ | ||||||
|  |  | ||||||
|  | #ifndef _PRCI_H_ | ||||||
|  | #define _PRCI_H_ | ||||||
|  |  | ||||||
|  | #include <sysc/tlm_target.h> | ||||||
|  |  | ||||||
|  | namespace sysc { | ||||||
|  |  | ||||||
|  | class prci_regs; | ||||||
|  |  | ||||||
|  | class prci : public sc_core::sc_module, public tlm_target<> { | ||||||
|  | public: | ||||||
|  |     SC_HAS_PROCESS(prci); | ||||||
|  |     sc_core::sc_in<sc_core::sc_time> clk_i; | ||||||
|  |     sc_core::sc_in<bool> rst_i; | ||||||
|  |     prci(sc_core::sc_module_name nm); | ||||||
|  |     virtual ~prci() override; // need to keep it in source file because of fwd declaration of prci_regs | ||||||
|  |  | ||||||
|  | protected: | ||||||
|  |     void clock_cb(); | ||||||
|  |     void reset_cb(); | ||||||
|  |     void hfrosc_en_cb(); | ||||||
|  |     sc_core::sc_time clk; | ||||||
|  |     std::unique_ptr<prci_regs> regs; | ||||||
|  |     sc_core::sc_event hfrosc_en_evt; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | } /* namespace sysc */ | ||||||
|  |  | ||||||
|  | #endif /* _GPIO_H_ */ | ||||||
| @@ -34,8 +34,10 @@ public: | |||||||
| protected: | protected: | ||||||
|     void clock_cb(); |     void clock_cb(); | ||||||
|     void reset_cb(); |     void reset_cb(); | ||||||
|  |     void transmit_data(); | ||||||
|     sc_core::sc_time clk; |     sc_core::sc_time clk; | ||||||
|     std::unique_ptr<uart_regs> regs; |     std::unique_ptr<uart_regs> regs; | ||||||
|  |     std::vector<uint8_t> queue; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| } /* namespace sysc */ | } /* namespace sysc */ | ||||||
|   | |||||||
| @@ -1,13 +1,9 @@ | |||||||
| # library files | # library files | ||||||
| FILE(GLOB RiscVSCHeaders *.h) | FILE(GLOB RiscVSCHeaders *.h) | ||||||
|  | FILE(GLOB RiscvSCSources sysc/*.cpp) | ||||||
|  |  | ||||||
| set(LIB_HEADERS ${RiscVSCHeaders} ) | set(LIB_HEADERS ${RiscVSCHeaders} ) | ||||||
| set(LIB_SOURCES | set(LIB_SOURCES ${RiscvSCSources} | ||||||
|     sysc/core_complex.cpp |  | ||||||
|     sysc/gpio.cpp |  | ||||||
|     sysc/plic.cpp |  | ||||||
|     sysc/platform.cpp |  | ||||||
|     sysc/spi.cpp |  | ||||||
|     sysc/uart.cpp |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| set(APP_HEADERS ) | set(APP_HEADERS ) | ||||||
|   | |||||||
| @@ -21,9 +21,12 @@ | |||||||
|  */ |  */ | ||||||
|  |  | ||||||
| #include <boost/program_options.hpp> | #include <boost/program_options.hpp> | ||||||
|  | #include <iss/jit/MCJIThelper.h> | ||||||
|  | #include <iss/log_categories.h> | ||||||
| #include <sr_report/sr_report.h> | #include <sr_report/sr_report.h> | ||||||
| #include <sstream> | #include <sstream> | ||||||
| #include <sysc/SiFive/platform.h> | #include <sysc/SiFive/platform.h> | ||||||
|  | #include <sysc/configurer.h> | ||||||
| #include <sysc/report.h> | #include <sysc/report.h> | ||||||
| #include <sysc/scv_tr_db.h> | #include <sysc/scv_tr_db.h> | ||||||
| #include <sysc/tracer.h> | #include <sysc/tracer.h> | ||||||
| @@ -39,19 +42,34 @@ const size_t ERROR_UNHANDLED_EXCEPTION = 2; | |||||||
|  |  | ||||||
| int sc_main(int argc, char *argv[]) { | int sc_main(int argc, char *argv[]) { | ||||||
|     //    sc_report_handler::set_handler(my_report_handler); |     //    sc_report_handler::set_handler(my_report_handler); | ||||||
|     sysc::Logger::reporting_level() = log::DEBUG; |     sysc::Logger<>::reporting_level() = log::ERROR; | ||||||
|     /////////////////////////////////////////////////////////////////////////// |     /////////////////////////////////////////////////////////////////////////// | ||||||
|     // CLI argument parsing |     // CLI argument parsing | ||||||
|     /////////////////////////////////////////////////////////////////////////// |     /////////////////////////////////////////////////////////////////////////// | ||||||
|     po::options_description desc("Options"); |     po::options_description desc("Options"); | ||||||
|     desc.add_options()("help,h", "Print help message")("debug,d", po::value<int>(), |     // clang-format off | ||||||
|                                                        "set debug level")("trace,t", "trace SystemC signals"); |     desc.add_options() | ||||||
|  |             ("help,h", "Print help message") | ||||||
|  |             ("verbose,v", po::value<int>()->implicit_value(0), "Sets logging verbosity") | ||||||
|  |             ("log-file", po::value<std::string>(), "Sets default log file.") | ||||||
|  |             ("disass,d", po::value<std::string>()->implicit_value(""), "Enables disassembly") | ||||||
|  | //            ("elf,l", po::value<std::vector<std::string>>(), "ELF file(s) to load") | ||||||
|  |             ("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") | ||||||
|  |             ("quantum", po::value<unsigned>(), "SystemC quantum time in ns") | ||||||
|  |             ("reset,r", po::value<std::string>(), "reset address") | ||||||
|  |             ("trace,t", po::value<uint8_t>()->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") | ||||||
|  |             ("config-file,c", po::value<std::string>()->default_value(""), "configuration file"); | ||||||
|  |     // clang-format on | ||||||
|     po::variables_map vm; |     po::variables_map vm; | ||||||
|     try { |     try { | ||||||
|         po::store(po::parse_command_line(argc, argv, desc), vm); // can throw |         po::store(po::parse_command_line(argc, argv, desc), vm); // can throw | ||||||
|         // --help option |         // --help option | ||||||
|         if (vm.count("help")) { |         if (vm.count("help")) { | ||||||
|             std::cout << "JIT-ISS simulator for AVR" << std::endl << desc << std::endl; |             std::cout << "DBT-RISE-RiscV simulator for RISC-V" << std::endl << desc << std::endl; | ||||||
|             return SUCCESS; |             return SUCCESS; | ||||||
|         } |         } | ||||||
|         po::notify(vm); // throws on error, so do after help in case |         po::notify(vm); // throws on error, so do after help in case | ||||||
| @@ -61,21 +79,65 @@ int sc_main(int argc, char *argv[]) { | |||||||
|         std::cerr << desc << std::endl; |         std::cerr << desc << std::endl; | ||||||
|         return ERROR_IN_COMMAND_LINE; |         return ERROR_IN_COMMAND_LINE; | ||||||
|     } |     } | ||||||
|  |     if (vm.count("verbose")) { | ||||||
|  |         auto l = logging::as_log_level(vm["verbose"].as<int>()); | ||||||
|  |         LOGGER(DEFAULT)::reporting_level() = l; | ||||||
|  |         LOGGER(connection)::reporting_level() = l; | ||||||
|  |         LOGGER(SystemC)::reporting_level() = l; | ||||||
|  |         sysc::Logger<>::reporting_level() = l; | ||||||
|  |     } | ||||||
|  |     if (vm.count("log-file")) { | ||||||
|  |         // configure the connection logger | ||||||
|  |         auto f = fopen(vm["log-file"].as<std::string>().c_str(), "w"); | ||||||
|  |         LOG_OUTPUT(DEFAULT)::stream() = f; | ||||||
|  |         LOG_OUTPUT(connection)::stream() = f; | ||||||
|  |         LOG_OUTPUT(SystemC)::stream() = f; | ||||||
|  |     } | ||||||
|  |     /////////////////////////////////////////////////////////////////////////// | ||||||
|  |     // set up infrastructure | ||||||
|  |     /////////////////////////////////////////////////////////////////////////// | ||||||
|  |     iss::init_jit(argc, argv); | ||||||
|     /////////////////////////////////////////////////////////////////////////// |     /////////////////////////////////////////////////////////////////////////// | ||||||
|     // set up tracing & transaction recording |     // set up tracing & transaction recording | ||||||
|     /////////////////////////////////////////////////////////////////////////// |     /////////////////////////////////////////////////////////////////////////// | ||||||
|     sysc::tracer trace("simple_system", sysc::tracer::TEXT, vm.count("trace")); |     sysc::tracer trace("simple_system", static_cast<sysc::tracer::file_type>(vm["trace"].as<uint8_t>() >> 1), | ||||||
|  |                        vm["trace"].as<uint8_t>() != 0); | ||||||
|  |     /////////////////////////////////////////////////////////////////////////// | ||||||
|  |     // set up configuration | ||||||
|  |     /////////////////////////////////////////////////////////////////////////// | ||||||
|  |     sysc::configurer cfg(vm["config-file"].as<std::string>()); | ||||||
|     /////////////////////////////////////////////////////////////////////////// |     /////////////////////////////////////////////////////////////////////////// | ||||||
|     // instantiate top level |     // instantiate top level | ||||||
|     /////////////////////////////////////////////////////////////////////////// |     /////////////////////////////////////////////////////////////////////////// | ||||||
|     platform i_simple_system("i_simple_system"); |     platform i_simple_system("i_simple_system"); | ||||||
|     // sr_report_handler::add_sc_object_to_filter(&i_simple_system.i_master, |     // sr_report_handler::add_sc_object_to_filter(&i_simple_system.i_master, | ||||||
|     // sc_core::SC_WARNING, sc_core::SC_MEDIUM); |     // sc_core::SC_WARNING, sc_core::SC_MEDIUM); | ||||||
|  |     // cfg.dump_hierarchy(); | ||||||
|  |     if (vm.count("elf")) cfg.set_value("i_simple_system.i_core_complex.elf_file", vm["elf"].as<std::string>()); | ||||||
|  |     if (vm.count("reset")) { | ||||||
|  |         auto str = vm["reset"].as<std::string>(); | ||||||
|  |         uint64_t start_address = str.find("0x") == 0 ? std::stoull(str.substr(2), 0, 16) : std::stoull(str, 0, 10); | ||||||
|  |         cfg.set_value("i_simple_system.i_core_complex.reset_address", start_address); | ||||||
|  |     } | ||||||
|  |     if (vm.count("disass")) { | ||||||
|  |         cfg.set_value("i_simple_system.i_core_complex.enable_disass", true); | ||||||
|  |         LOGGER(disass)::reporting_level() = logging::INFO; | ||||||
|  |         auto file_name = vm["disass"].as<std::string>(); | ||||||
|  |         if (file_name.length() > 0) { | ||||||
|  |             LOG_OUTPUT(disass)::stream() = fopen(file_name.c_str(), "w"); | ||||||
|  |             LOGGER(disass)::print_time() = false; | ||||||
|  |             LOGGER(disass)::print_severity() = false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     cfg.set_value("i_simple_system.i_core_complex.gdb_server_port", vm["gdb-port"].as<unsigned short>()); | ||||||
|  |     cfg.set_value("i_simple_system.i_core_complex.dump_ir", vm.count("dump-ir") != 0); | ||||||
|  |     if (vm.count("quantum")) { | ||||||
|  |         tlm::tlm_global_quantum::instance().set(sc_core::sc_time(vm["quantum"].as<unsigned>(), sc_core::SC_NS)); | ||||||
|  |     } | ||||||
|     /////////////////////////////////////////////////////////////////////////// |     /////////////////////////////////////////////////////////////////////////// | ||||||
|     // run simulation |     // run simulation | ||||||
|     /////////////////////////////////////////////////////////////////////////// |     /////////////////////////////////////////////////////////////////////////// | ||||||
|     sc_start(sc_core::sc_time(100, sc_core::SC_NS)); |     sc_start(); | ||||||
|     if (!sc_end_of_simulation_invoked()) sc_stop(); |     if (!sc_end_of_simulation_invoked()) sc_stop(); | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										48
									
								
								riscv.sc/src/sysc/aon.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								riscv.sc/src/sysc/aon.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | |||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | // Copyright 2017 eyck@minres.com | ||||||
|  | // | ||||||
|  | // Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||||||
|  | // use this file except in compliance with the License.  You may obtain a copy | ||||||
|  | // of the License at | ||||||
|  | // | ||||||
|  | //   http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | // | ||||||
|  | // Unless required by applicable law or agreed to in writing, software | ||||||
|  | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||||
|  | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the | ||||||
|  | // License for the specific language governing permissions and limitations under | ||||||
|  | // the License. | ||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | #include "sysc/SiFive/aon.h" | ||||||
|  | #include "sysc/SiFive/gen/aon_regs.h" | ||||||
|  | #include "sysc/utilities.h" | ||||||
|  |  | ||||||
|  | namespace sysc { | ||||||
|  |  | ||||||
|  | aon::aon(sc_core::sc_module_name nm) | ||||||
|  | : sc_core::sc_module(nm) | ||||||
|  | , tlm_target<>(clk) | ||||||
|  | , NAMED(clk_i) | ||||||
|  | , NAMED(rst_i) | ||||||
|  | , NAMEDD(aon_regs, regs) { | ||||||
|  |     regs->registerResources(*this); | ||||||
|  |     SC_METHOD(clock_cb); | ||||||
|  |     sensitive << clk_i; | ||||||
|  |     SC_METHOD(reset_cb); | ||||||
|  |     sensitive << rst_i; | ||||||
|  |     dont_initialize(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void aon::clock_cb() {} | ||||||
|  |  | ||||||
|  | aon::~aon() {} | ||||||
|  |  | ||||||
|  | void aon::reset_cb() { | ||||||
|  |     if (rst_i.read()) | ||||||
|  |         regs->reset_start(); | ||||||
|  |     else | ||||||
|  |         regs->reset_stop(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } /* namespace sysc */ | ||||||
							
								
								
									
										95
									
								
								riscv.sc/src/sysc/clint.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								riscv.sc/src/sysc/clint.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,95 @@ | |||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | // Copyright 2017 eyck@minres.com | ||||||
|  | // | ||||||
|  | // Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||||||
|  | // use this file except in compliance with the License.  You may obtain a copy | ||||||
|  | // of the License at | ||||||
|  | // | ||||||
|  | //   http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | // | ||||||
|  | // Unless required by applicable law or agreed to in writing, software | ||||||
|  | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||||
|  | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the | ||||||
|  | // License for the specific language governing permissions and limitations under | ||||||
|  | // the License. | ||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | #include "sysc/SiFive/clint.h" | ||||||
|  | #include "sysc/SiFive/gen/clint_regs.h" | ||||||
|  | #include "sysc/utilities.h" | ||||||
|  |  | ||||||
|  | namespace sysc { | ||||||
|  |  | ||||||
|  | const int lfclk_mutiplier = 1 << 12; | ||||||
|  |  | ||||||
|  | clint::clint(sc_core::sc_module_name nm) | ||||||
|  | : sc_core::sc_module(nm) | ||||||
|  | , tlm_target<>(clk) | ||||||
|  | , NAMED(clk_i) | ||||||
|  | , NAMED(rst_i) | ||||||
|  | , NAMED(mtime_int_o) | ||||||
|  | , NAMED(msip_int_o) | ||||||
|  | , NAMEDD(clint_regs, regs) | ||||||
|  | , cnt_fraction(0) { | ||||||
|  |     regs->registerResources(*this); | ||||||
|  |     SC_METHOD(clock_cb); | ||||||
|  |     sensitive << clk_i; | ||||||
|  |     SC_METHOD(reset_cb); | ||||||
|  |     sensitive << rst_i; | ||||||
|  |     dont_initialize(); | ||||||
|  |     regs->mtimecmp.set_write_cb([this](sc_register<uint64_t> ®, uint64_t data) -> bool { | ||||||
|  |         if (!regs->in_reset()) { | ||||||
|  |             reg.put(data); | ||||||
|  |             this->update_mtime(); | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     }); | ||||||
|  |     regs->mtime.set_read_cb([this](const sc_register<uint64_t> ®, uint64_t &data) -> bool { | ||||||
|  |         this->update_mtime(); | ||||||
|  |         data = reg.get(); | ||||||
|  |         return true; | ||||||
|  |     }); | ||||||
|  |     regs->mtime.set_write_cb([this](sc_register<uint64_t> ®, uint64_t data) -> bool { return false; }); | ||||||
|  |     regs->msip.set_write_cb([this](sc_register<uint32_t> ®, uint32_t data) -> bool { | ||||||
|  |         reg.put(data); | ||||||
|  |         msip_int_o.write(regs->r_msip.msip); | ||||||
|  |         return true; | ||||||
|  |     }); | ||||||
|  |     SC_METHOD(update_mtime); | ||||||
|  |     sensitive << mtime_evt; | ||||||
|  |     dont_initialize(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void clint::clock_cb() { | ||||||
|  |     update_mtime(); | ||||||
|  |     clk = clk_i.read(); | ||||||
|  |     update_mtime(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | clint::~clint() {} | ||||||
|  |  | ||||||
|  | void clint::reset_cb() { | ||||||
|  |     if (rst_i.read()) { | ||||||
|  |         regs->reset_start(); | ||||||
|  |         msip_int_o.write(false); | ||||||
|  |         mtime_int_o.write(false); | ||||||
|  |         cnt_fraction = 0; | ||||||
|  |     } else | ||||||
|  |         regs->reset_stop(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void clint::update_mtime() { | ||||||
|  |     auto diff = (sc_time_stamp() - last_updt) / clk; | ||||||
|  |     auto diffi = (int)diff; | ||||||
|  |     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_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); | ||||||
|  |     last_updt = sc_time_stamp(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } /* namespace sysc */ | ||||||
| @@ -34,16 +34,222 @@ | |||||||
| // | // | ||||||
| //////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | #include <iss/arch/riscv_hart_msu_vp.h> | ||||||
|  | #include <iss/arch/rv32imac.h> | ||||||
|  | #include <iss/iss.h> | ||||||
|  | #include <iss/vm_types.h> | ||||||
| #include <sysc/SiFive/core_complex.h> | #include <sysc/SiFive/core_complex.h> | ||||||
|  | #include <sysc/report.h> | ||||||
|  |  | ||||||
| namespace sysc { | namespace sysc { | ||||||
| namespace SiFive { | namespace SiFive { | ||||||
|  |  | ||||||
|  | class core_wrapper : public iss::arch::riscv_hart_msu_vp<iss::arch::rv32imac> { | ||||||
|  | public: | ||||||
|  |     using core_type = iss::arch::rv32imac; | ||||||
|  |     using base_type = iss::arch::riscv_hart_msu_vp<iss::arch::rv32imac>; | ||||||
|  |     using phys_addr_t = typename iss::arch::traits<iss::arch::rv32imac>::phys_addr_t; | ||||||
|  |     core_wrapper(core_complex *owner) | ||||||
|  |     : owner(owner) {} | ||||||
|  |  | ||||||
|  |     void notify_phase(iss::arch_if::exec_phase phase); | ||||||
|  |  | ||||||
|  |     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) ? 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; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |     core_complex *const owner; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | void core_wrapper::notify_phase(exec_phase phase) { | ||||||
|  |     core_type::notify_phase(phase); | ||||||
|  |     if (phase == ISTART) owner->sync(); | ||||||
|  | } | ||||||
|  |  | ||||||
| core_complex::core_complex(sc_core::sc_module_name name) | core_complex::core_complex(sc_core::sc_module_name name) | ||||||
| : sc_core::sc_module(name) | : sc_core::sc_module(name) | ||||||
| , NAMED(initiator) | , NAMED(initiator) | ||||||
| , NAMED(rst_i) { | , NAMED(clk_i) | ||||||
|     // TODO Auto-generated constructor stub | , NAMED(rst_i) | ||||||
|  | , NAMED(elf_file, this) | ||||||
|  | , NAMED(enable_disass, true, this) | ||||||
|  | , NAMED(reset_address, 0ULL, this) | ||||||
|  | , NAMED(gdb_server_port, 0, this) | ||||||
|  | , NAMED(dump_ir, false, this) | ||||||
|  | , read_lut(tlm_dmi_ext()) | ||||||
|  | , write_lut(tlm_dmi_ext()) { | ||||||
|  |  | ||||||
|  |     initiator.register_invalidate_direct_mem_ptr([=](uint64_t start, uint64_t end) -> void { | ||||||
|  |         auto lut_entry = read_lut.getEntry(start); | ||||||
|  |         if (lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && end <= lut_entry.get_end_address() + 1) { | ||||||
|  |             read_lut.removeEntry(lut_entry); | ||||||
|  |         } | ||||||
|  |         lut_entry = write_lut.getEntry(start); | ||||||
|  |         if (lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && end <= lut_entry.get_end_address() + 1) { | ||||||
|  |             write_lut.removeEntry(lut_entry); | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  |  | ||||||
|  |     SC_THREAD(run); | ||||||
|  |     SC_METHOD(clk_cb); | ||||||
|  |     sensitive << clk_i; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | core_complex::~core_complex() = default; | ||||||
|  |  | ||||||
|  | void core_complex::trace(sc_core::sc_trace_file *trf) {} | ||||||
|  |  | ||||||
|  | void core_complex::before_end_of_elaboration() { | ||||||
|  |     cpu = std::make_unique<core_wrapper>(this); | ||||||
|  |     vm = iss::create<iss::arch::rv32imac>(cpu.get(), gdb_server_port.value, dump_ir.value); | ||||||
|  |     vm->setDisassEnabled(enable_disass.value); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void core_complex::start_of_simulation() { | ||||||
|  |     quantum_keeper.reset(); | ||||||
|  |     if (elf_file.value.size() > 0) cpu->load_file(elf_file.value); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void core_complex::clk_cb() { curr_clk = clk_i.read(); } | ||||||
|  |  | ||||||
|  | void core_complex::run() { | ||||||
|  |     wait(sc_core::SC_ZERO_TIME); | ||||||
|  |     cpu->reset(reset_address.value); | ||||||
|  |     try { | ||||||
|  |         vm->start(-1); | ||||||
|  |     } catch (iss::simulation_stopped &e) { | ||||||
|  |     } | ||||||
|  |     sc_core::sc_stop(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool core_complex::read_mem(uint64_t addr, unsigned length, uint8_t *const data) { | ||||||
|  |     auto lut_entry = read_lut.getEntry(addr); | ||||||
|  |     if (lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && | ||||||
|  |         addr + length <= lut_entry.get_end_address() + 1) { | ||||||
|  |         auto offset = addr - lut_entry.get_start_address(); | ||||||
|  |         std::copy(lut_entry.get_dmi_ptr() + offset, lut_entry.get_dmi_ptr() + offset + length, data); | ||||||
|  |         quantum_keeper.inc(lut_entry.get_read_latency()); | ||||||
|  |         return true; | ||||||
|  |     } else { | ||||||
|  |         tlm::tlm_generic_payload gp; | ||||||
|  |         gp.set_command(tlm::TLM_READ_COMMAND); | ||||||
|  |         gp.set_address(addr); | ||||||
|  |         gp.set_data_ptr(data); | ||||||
|  |         gp.set_data_length(length); | ||||||
|  |         gp.set_streaming_width(4); | ||||||
|  |         auto delay{quantum_keeper.get_local_time()}; | ||||||
|  |         initiator->b_transport(gp, delay); | ||||||
|  |         LOG(TRACE) << "read_mem(0x" << std::hex << addr << ") : " << data; | ||||||
|  |         if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         if (gp.is_dmi_allowed()) { | ||||||
|  |             gp.set_command(tlm::TLM_READ_COMMAND); | ||||||
|  |             gp.set_address(addr); | ||||||
|  |             tlm_dmi_ext dmi_data; | ||||||
|  |             if (initiator->get_direct_mem_ptr(gp, dmi_data)) { | ||||||
|  |                 if (dmi_data.is_read_allowed()) | ||||||
|  |                     read_lut.addEntry(dmi_data, dmi_data.get_start_address(), | ||||||
|  |                                       dmi_data.get_end_address() - dmi_data.get_start_address() + 1); | ||||||
|  |                 if (dmi_data.is_write_allowed()) | ||||||
|  |                     write_lut.addEntry(dmi_data, dmi_data.get_start_address(), | ||||||
|  |                                        dmi_data.get_end_address() - dmi_data.get_start_address() + 1); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool core_complex::write_mem(uint64_t addr, unsigned length, const uint8_t *const data) { | ||||||
|  |     auto lut_entry = write_lut.getEntry(addr); | ||||||
|  |     if (lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && | ||||||
|  |         addr + length <= lut_entry.get_end_address() + 1) { | ||||||
|  |         auto offset = addr - lut_entry.get_start_address(); | ||||||
|  |         std::copy(data, data + length, lut_entry.get_dmi_ptr() + offset); | ||||||
|  |         quantum_keeper.inc(lut_entry.get_read_latency()); | ||||||
|  |         return true; | ||||||
|  |     } else { | ||||||
|  |         write_buf.resize(length); | ||||||
|  |         std::copy(data, data + length, write_buf.begin()); // need to copy as TLM does not guarantee data integrity | ||||||
|  |         tlm::tlm_generic_payload gp; | ||||||
|  |         gp.set_command(tlm::TLM_WRITE_COMMAND); | ||||||
|  |         gp.set_address(addr); | ||||||
|  |         gp.set_data_ptr(write_buf.data()); | ||||||
|  |         gp.set_data_length(length); | ||||||
|  |         gp.set_streaming_width(4); | ||||||
|  |         auto delay{quantum_keeper.get_local_time()}; | ||||||
|  |         initiator->b_transport(gp, delay); | ||||||
|  |         quantum_keeper.set(delay); | ||||||
|  |         LOG(TRACE) << "write_mem(0x" << std::hex << addr << ") : " << data; | ||||||
|  |         if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         if (gp.is_dmi_allowed()) { | ||||||
|  |             gp.set_command(tlm::TLM_READ_COMMAND); | ||||||
|  |             gp.set_address(addr); | ||||||
|  |             tlm_dmi_ext dmi_data; | ||||||
|  |             if (initiator->get_direct_mem_ptr(gp, dmi_data)) { | ||||||
|  |                 if (dmi_data.is_read_allowed()) | ||||||
|  |                     read_lut.addEntry(dmi_data, dmi_data.get_start_address(), | ||||||
|  |                                       dmi_data.get_end_address() - dmi_data.get_start_address() + 1); | ||||||
|  |                 if (dmi_data.is_write_allowed()) | ||||||
|  |                     write_lut.addEntry(dmi_data, dmi_data.get_start_address(), | ||||||
|  |                                        dmi_data.get_end_address() - dmi_data.get_start_address() + 1); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool core_complex::read_mem_dbg(uint64_t addr, unsigned length, uint8_t *const data) { | ||||||
|  |     auto lut_entry = read_lut.getEntry(addr); | ||||||
|  |     if (lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && | ||||||
|  |         addr + length <= lut_entry.get_end_address() + 1) { | ||||||
|  |         auto offset = addr - lut_entry.get_start_address(); | ||||||
|  |         std::copy(lut_entry.get_dmi_ptr() + offset, lut_entry.get_dmi_ptr() + offset + length, data); | ||||||
|  |         quantum_keeper.inc(lut_entry.get_read_latency()); | ||||||
|  |         return true; | ||||||
|  |     } else { | ||||||
|  |         tlm::tlm_generic_payload gp; | ||||||
|  |         gp.set_command(tlm::TLM_READ_COMMAND); | ||||||
|  |         gp.set_address(addr); | ||||||
|  |         gp.set_data_ptr(data); | ||||||
|  |         gp.set_data_length(length); | ||||||
|  |         gp.set_streaming_width(length); | ||||||
|  |         return initiator->transport_dbg(gp) == length; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | bool core_complex::write_mem_dbg(uint64_t addr, unsigned length, const uint8_t *const data) { | ||||||
|  |     auto lut_entry = write_lut.getEntry(addr); | ||||||
|  |     if (lut_entry.get_granted_access() != tlm::tlm_dmi::DMI_ACCESS_NONE && | ||||||
|  |         addr + length <= lut_entry.get_end_address() + 1) { | ||||||
|  |         auto offset = addr - lut_entry.get_start_address(); | ||||||
|  |         std::copy(data, data + length, lut_entry.get_dmi_ptr() + offset); | ||||||
|  |         quantum_keeper.inc(lut_entry.get_read_latency()); | ||||||
|  |         return true; | ||||||
|  |     } else { | ||||||
|  |         write_buf.resize(length); | ||||||
|  |         std::copy(data, data + length, write_buf.begin()); // need to copy as TLM does not guarantee data integrity | ||||||
|  |         tlm::tlm_generic_payload gp; | ||||||
|  |         gp.set_command(tlm::TLM_WRITE_COMMAND); | ||||||
|  |         gp.set_address(addr); | ||||||
|  |         gp.set_data_ptr(write_buf.data()); | ||||||
|  |         gp.set_data_length(length); | ||||||
|  |         gp.set_streaming_width(length); | ||||||
|  |         return initiator->transport_dbg(gp) == length; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| } /* namespace SiFive */ | } /* namespace SiFive */ | ||||||
|   | |||||||
| @@ -31,6 +31,7 @@ gpio::gpio(sc_core::sc_module_name nm) | |||||||
|     sensitive << clk_i; |     sensitive << clk_i; | ||||||
|     SC_METHOD(reset_cb); |     SC_METHOD(reset_cb); | ||||||
|     sensitive << rst_i; |     sensitive << rst_i; | ||||||
|  |     dont_initialize(); | ||||||
| } | } | ||||||
|  |  | ||||||
| void gpio::clock_cb() {} | void gpio::clock_cb() {} | ||||||
|   | |||||||
| @@ -26,37 +26,60 @@ namespace sysc { | |||||||
|  |  | ||||||
| platform::platform(sc_core::sc_module_name nm) | platform::platform(sc_core::sc_module_name nm) | ||||||
| : sc_core::sc_module(nm) | : sc_core::sc_module(nm) | ||||||
| , NAMED(i_master) | , NAMED(i_core_complex) | ||||||
| , NAMED(i_router, 4, 1) | , NAMED(i_router, 10, 1) | ||||||
| , NAMED(i_uart) | , NAMED(i_uart0) | ||||||
|  | , NAMED(i_uart1) | ||||||
| , NAMED(i_spi) | , NAMED(i_spi) | ||||||
| , NAMED(i_gpio) | , NAMED(i_gpio) | ||||||
| , NAMED(i_plic) | , NAMED(i_plic) | ||||||
|  | , NAMED(i_aon) | ||||||
|  | , NAMED(i_prci) | ||||||
|  | , NAMED(i_clint) | ||||||
|  | , NAMED(i_mem_qspi) | ||||||
|  | , NAMED(i_mem_ram) | ||||||
| , NAMED(s_clk) | , NAMED(s_clk) | ||||||
| , NAMED(s_rst) { | , NAMED(s_rst) { | ||||||
|     i_master.initiator(i_router.target[0]); |     i_core_complex.initiator(i_router.target[0]); | ||||||
|     size_t i = 0; |     size_t i = 0; | ||||||
|     for (const auto &e : e300_plat_map) { |     for (const auto &e : e300_plat_map) { | ||||||
|         i_router.initiator.at(i)(e.target->socket); |         i_router.initiator.at(i)(e.target->socket); | ||||||
|         i_router.add_target_range(i, e.start, e.size); |         i_router.add_target_range(i, e.start, e.size); | ||||||
|         i++; |         i++; | ||||||
|     } |     } | ||||||
|     i_uart.clk_i(s_clk); |     i_router.initiator.at(i)(i_mem_qspi.target); | ||||||
|  |     i_router.add_target_range(i, 0x20000000, 512_MB); | ||||||
|  |     i_router.initiator.at(++i)(i_mem_ram.target); | ||||||
|  |     i_router.add_target_range(i, 0x80000000, 128_kB); | ||||||
|  |  | ||||||
|  |     i_uart0.clk_i(s_clk); | ||||||
|  |     i_uart1.clk_i(s_clk); | ||||||
|     i_spi.clk_i(s_clk); |     i_spi.clk_i(s_clk); | ||||||
|     i_gpio.clk_i(s_clk); |     i_gpio.clk_i(s_clk); | ||||||
|     i_plic.clk_i(s_clk); |     i_plic.clk_i(s_clk); | ||||||
|     s_clk.write(10_ns); |     i_aon.clk_i(s_clk); | ||||||
|  |     i_prci.clk_i(s_clk); | ||||||
|  |     i_clint.clk_i(s_clk); | ||||||
|  |     i_core_complex.clk_i(s_clk); | ||||||
|  |  | ||||||
|     i_uart.rst_i(s_rst); |     i_uart0.rst_i(s_rst); | ||||||
|  |     i_uart1.rst_i(s_rst); | ||||||
|     i_spi.rst_i(s_rst); |     i_spi.rst_i(s_rst); | ||||||
|     i_gpio.rst_i(s_rst); |     i_gpio.rst_i(s_rst); | ||||||
|     i_plic.rst_i(s_rst); |     i_plic.rst_i(s_rst); | ||||||
|     i_master.rst_i(s_rst); |     i_aon.rst_i(s_rst); | ||||||
|  |     i_prci.rst_i(s_rst); | ||||||
|  |     i_clint.rst_i(s_rst); | ||||||
|  |     i_core_complex.rst_i(s_rst); | ||||||
|  |  | ||||||
|  |     i_clint.mtime_int_o(s_mtime_int); | ||||||
|  |     i_clint.msip_int_o(s_msie_int); | ||||||
|  |  | ||||||
|     SC_THREAD(gen_reset); |     SC_THREAD(gen_reset); | ||||||
| } | } | ||||||
|  |  | ||||||
| void platform::gen_reset() { | void platform::gen_reset() { | ||||||
|  |     s_clk = 10_ns; | ||||||
|     s_rst = true; |     s_rst = true; | ||||||
|     wait(10_ns); |     wait(10_ns); | ||||||
|     s_rst = false; |     s_rst = false; | ||||||
|   | |||||||
| @@ -31,6 +31,7 @@ plic::plic(sc_core::sc_module_name nm) | |||||||
|     sensitive << clk_i; |     sensitive << clk_i; | ||||||
|     SC_METHOD(reset_cb); |     SC_METHOD(reset_cb); | ||||||
|     sensitive << rst_i; |     sensitive << rst_i; | ||||||
|  |     dont_initialize(); | ||||||
| } | } | ||||||
|  |  | ||||||
| plic::~plic() {} | plic::~plic() {} | ||||||
|   | |||||||
							
								
								
									
										71
									
								
								riscv.sc/src/sysc/prci.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								riscv.sc/src/sysc/prci.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | |||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  | // Copyright 2017 eyck@minres.com | ||||||
|  | // | ||||||
|  | // Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||||||
|  | // use this file except in compliance with the License.  You may obtain a copy | ||||||
|  | // of the License at | ||||||
|  | // | ||||||
|  | //   http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | // | ||||||
|  | // Unless required by applicable law or agreed to in writing, software | ||||||
|  | // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||||
|  | // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the | ||||||
|  | // License for the specific language governing permissions and limitations under | ||||||
|  | // the License. | ||||||
|  | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
|  | #include "sysc/SiFive/prci.h" | ||||||
|  | #include "sysc/SiFive/gen/prci_regs.h" | ||||||
|  | #include "sysc/utilities.h" | ||||||
|  |  | ||||||
|  | namespace sysc { | ||||||
|  |  | ||||||
|  | prci::prci(sc_core::sc_module_name nm) | ||||||
|  | : sc_core::sc_module(nm) | ||||||
|  | , tlm_target<>(clk) | ||||||
|  | , NAMED(clk_i) | ||||||
|  | , NAMED(rst_i) | ||||||
|  | , NAMEDD(prci_regs, regs) { | ||||||
|  |     regs->registerResources(*this); | ||||||
|  |     SC_METHOD(clock_cb); | ||||||
|  |     sensitive << clk_i; | ||||||
|  |     SC_METHOD(reset_cb); | ||||||
|  |     sensitive << rst_i; | ||||||
|  |     dont_initialize(); | ||||||
|  |     SC_METHOD(hfrosc_en_cb); | ||||||
|  |     sensitive << hfrosc_en_evt; | ||||||
|  |     dont_initialize(); | ||||||
|  |  | ||||||
|  |     regs->hfrosccfg.set_write_cb([this](sysc::sc_register<uint32_t> ®, uint32_t data) -> bool { | ||||||
|  |         reg.put(data); | ||||||
|  |         if (this->regs->r_hfrosccfg & (1 << 30)) { // check rosc_en | ||||||
|  |             this->hfrosc_en_evt.notify(1, sc_core::SC_US); | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     }); | ||||||
|  |     regs->pllcfg.set_write_cb([this](sysc::sc_register<uint32_t> ®, uint32_t data) -> bool { | ||||||
|  |         reg.put(data); | ||||||
|  |         auto &pllcfg = this->regs->r_pllcfg; | ||||||
|  |         if (pllcfg.pllbypass == 0 && pllcfg.pllq != 0) { // set pll_lock if pll is selected | ||||||
|  |             pllcfg.plllock = 1; | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     }); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void prci::clock_cb() {} | ||||||
|  |  | ||||||
|  | prci::~prci() {} | ||||||
|  |  | ||||||
|  | void prci::reset_cb() { | ||||||
|  |     if (rst_i.read()) | ||||||
|  |         regs->reset_start(); | ||||||
|  |     else | ||||||
|  |         regs->reset_stop(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void prci::hfrosc_en_cb() { | ||||||
|  |     regs->r_hfrosccfg |= (1 << 31); // set rosc_rdy | ||||||
|  | } | ||||||
|  |  | ||||||
|  | } /* namespace sysc */ | ||||||
| @@ -31,6 +31,7 @@ spi::spi(sc_core::sc_module_name nm) | |||||||
|     sensitive << clk_i; |     sensitive << clk_i; | ||||||
|     SC_METHOD(reset_cb); |     SC_METHOD(reset_cb); | ||||||
|     sensitive << rst_i; |     sensitive << rst_i; | ||||||
|  |     dont_initialize(); | ||||||
| } | } | ||||||
|  |  | ||||||
| spi::~spi() {} | spi::~spi() {} | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ | |||||||
|  |  | ||||||
| #include "sysc/SiFive/uart.h" | #include "sysc/SiFive/uart.h" | ||||||
| #include "sysc/SiFive/gen/uart_regs.h" | #include "sysc/SiFive/gen/uart_regs.h" | ||||||
|  | #include "sysc/report.h" | ||||||
| #include "sysc/utilities.h" | #include "sysc/utilities.h" | ||||||
|  |  | ||||||
| namespace sysc { | namespace sysc { | ||||||
| @@ -31,6 +32,14 @@ uart::uart(sc_core::sc_module_name nm) | |||||||
|     sensitive << clk_i; |     sensitive << clk_i; | ||||||
|     SC_METHOD(reset_cb); |     SC_METHOD(reset_cb); | ||||||
|     sensitive << rst_i; |     sensitive << rst_i; | ||||||
|  |     dont_initialize(); | ||||||
|  |     regs->txdata.set_write_cb([this](sc_register<uint32_t> ®, uint32_t data) -> bool { | ||||||
|  |         if (!this->regs->in_reset()) { | ||||||
|  |             reg.put(data); | ||||||
|  |             this->transmit_data(); | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
| uart::~uart() {} | uart::~uart() {} | ||||||
| @@ -44,4 +53,13 @@ void uart::reset_cb() { | |||||||
|         regs->reset_stop(); |         regs->reset_stop(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void uart::transmit_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()) << "'"; | ||||||
|  |         queue.clear(); | ||||||
|  |     } else { | ||||||
|  |         queue.push_back(regs->r_txdata.data); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| } /* namespace sysc */ | } /* namespace sysc */ | ||||||
|   | |||||||
| @@ -1,81 +0,0 @@ | |||||||
| /******************************************************************************* |  | ||||||
|  * Copyright (C) 2017, MINRES Technologies GmbH |  | ||||||
|  * All rights reserved. |  | ||||||
|  * |  | ||||||
|  * Redistribution and use in source and binary forms, with or without |  | ||||||
|  * modification, are permitted provided that the following conditions are met: |  | ||||||
|  * |  | ||||||
|  * 1. Redistributions of source code must retain the above copyright notice, |  | ||||||
|  *    this list of conditions and the following disclaimer. |  | ||||||
|  * |  | ||||||
|  * 2. Redistributions in binary form must reproduce the above copyright notice, |  | ||||||
|  *    this list of conditions and the following disclaimer in the documentation |  | ||||||
|  *    and/or other materials provided with the distribution. |  | ||||||
|  * |  | ||||||
|  * 3. Neither the name of the copyright holder nor the names of its contributors |  | ||||||
|  *    may be used to endorse or promote products derived from this software |  | ||||||
|  *    without specific prior written permission. |  | ||||||
|  * |  | ||||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |  | ||||||
|  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |  | ||||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |  | ||||||
|  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |  | ||||||
|  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |  | ||||||
|  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |  | ||||||
|  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |  | ||||||
|  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |  | ||||||
|  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |  | ||||||
|  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |  | ||||||
|  * POSSIBILITY OF SUCH DAMAGE. |  | ||||||
|  * |  | ||||||
|  * Contributors: |  | ||||||
|  *       eyck@minres.com - initial API and implementation |  | ||||||
|  ******************************************************************************/ |  | ||||||
|  |  | ||||||
| #ifndef _CLI_OPTIONS_H_ |  | ||||||
| #define _CLI_OPTIONS_H_ |  | ||||||
| #include <boost/program_options.hpp> |  | ||||||
| #include <cstdio> |  | ||||||
| #include <iostream> |  | ||||||
| #include <util/logging.h> |  | ||||||
|  |  | ||||||
| const size_t ERROR_IN_COMMAND_LINE = 1; |  | ||||||
| const size_t SUCCESS = 0; |  | ||||||
| const size_t ERROR_UNHANDLED_EXCEPTION = 2; |  | ||||||
|  |  | ||||||
| inline int parse_cli_options(boost::program_options::variables_map &vm, int argc, char *argv[]) { |  | ||||||
|     namespace po = boost::program_options; |  | ||||||
|     po::options_description desc("Options"); |  | ||||||
|     desc.add_options()("help,h", "Print help message")("verbose,v", po::value<int>()->implicit_value(0), |  | ||||||
|                                                        "Sets logging verbosity")("vmodule", po::value<std::string>(), |  | ||||||
|                                                                                  "Defines the module(s) to be logged")( |  | ||||||
|         "logging-flags", po::value<int>(), "Sets logging flag(s).")("log-file", po::value<std::string>(), |  | ||||||
|                                                                     "Sets default log file.")( |  | ||||||
|         "disass,d", po::value<std::string>()->implicit_value(""), |  | ||||||
|         "Enables disassembly")("elf,l", po::value<std::vector<std::string>>(), "ELF file(s) to load")( |  | ||||||
|         "gdb-port,g", po::value<unsigned>(), "enable gdb server and specify port to use")( |  | ||||||
|         "input,i", po::value<std::string>(), "the elf file to load (instead of hex files)")( |  | ||||||
|         "dump-ir", "dump the intermediate representation")("cycles,c", po::value<int64_t>()->default_value(-1), |  | ||||||
|                                                            "number of cycles to run")( |  | ||||||
|         "systemc,s", "Run as SystemC simulation")("time", po::value<int>(), "SystemC siimulation time in ms")( |  | ||||||
|         "reset,r", po::value<std::string>(), "reset address")( |  | ||||||
|         "trace", po::value<uint8_t>(), "enable tracing, or cmbintation of 1=signals and 2=TX text, 4=TX " |  | ||||||
|                                        "compressed text, 6=TX in SQLite")("mem,m", po::value<std::string>(), |  | ||||||
|                                                                           "the memory input file")("rv64", "run RV64"); |  | ||||||
|     try { |  | ||||||
|         po::store(po::parse_command_line(argc, argv, desc), vm); // can throw |  | ||||||
|         // --help option |  | ||||||
|         if (vm.count("help")) { |  | ||||||
|             std::cout << "DBT-RISE-RiscV" << std::endl << desc << std::endl; |  | ||||||
|             return SUCCESS; |  | ||||||
|         } |  | ||||||
|         po::notify(vm); // throws on error, so do after help in case |  | ||||||
|     } catch (po::error &e) { |  | ||||||
|         // there are problems |  | ||||||
|         std::cerr << "ERROR: " << e.what() << std::endl << std::endl; |  | ||||||
|         std::cerr << desc << std::endl; |  | ||||||
|         return ERROR_IN_COMMAND_LINE; |  | ||||||
|     } |  | ||||||
|     return SUCCESS; |  | ||||||
| } |  | ||||||
| #endif /* _CLI_OPTIONS_H_ */ |  | ||||||
| @@ -431,7 +431,7 @@ template <typename BASE> struct riscv_hart_msu_vp : public BASE { | |||||||
|     riscv_hart_msu_vp(); |     riscv_hart_msu_vp(); | ||||||
|     virtual ~riscv_hart_msu_vp() = default; |     virtual ~riscv_hart_msu_vp() = default; | ||||||
|  |  | ||||||
|     virtual void load_file(std::string name, int type = -1); |     void load_file(std::string name, int type = -1) override; | ||||||
|  |  | ||||||
|     virtual phys_addr_t v2p(const iss::addr_t &addr); |     virtual phys_addr_t v2p(const iss::addr_t &addr); | ||||||
|  |  | ||||||
| @@ -550,9 +550,12 @@ template <typename BASE> void riscv_hart_msu_vp<BASE>::load_file(std::string nam | |||||||
|                 const auto fsize = pseg->get_file_size(); // 0x42c/0x0 |                 const auto fsize = pseg->get_file_size(); // 0x42c/0x0 | ||||||
|                 const auto seg_data = pseg->get_data(); |                 const auto seg_data = pseg->get_data(); | ||||||
|                 if (fsize > 0) { |                 if (fsize > 0) { | ||||||
|                     this->write( |                     auto res = this->write( | ||||||
|                         typed_addr_t<PHYSICAL>(iss::DEBUG_WRITE, traits<BASE>::MEM, pseg->get_virtual_address()), fsize, |                         typed_addr_t<PHYSICAL>(iss::DEBUG_WRITE, traits<BASE>::MEM, pseg->get_physical_address()), | ||||||
|                         reinterpret_cast<const uint8_t *const>(seg_data)); |                         fsize, reinterpret_cast<const uint8_t *const>(seg_data)); | ||||||
|  |                     if (res != iss::Ok) | ||||||
|  |                         LOG(ERROR) << "problem writing " << fsize << "bytes to 0x" << std::hex | ||||||
|  |                                    << pseg->get_physical_address(); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             for (const auto sec : reader.sections) { |             for (const auto sec : reader.sections) { | ||||||
| @@ -596,20 +599,9 @@ iss::status riscv_hart_msu_vp<BASE>::read(const iss::addr_t &addr, unsigned leng | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             phys_addr_t paddr = (addr.type & iss::ADDRESS_TYPE) == iss::PHYSICAL ? addr : v2p(addr); |             phys_addr_t paddr = (addr.type & iss::ADDRESS_TYPE) == iss::PHYSICAL ? addr : v2p(addr); | ||||||
|             if ((paddr.val + length) > mem.size()) return iss::Err; |             auto res = read_mem(paddr, length, data); | ||||||
|             switch (paddr.val) { |             if (res != iss::Ok) this->reg.trap_state = (1 << 31) | (5 << 16); // issue trap 5 (load access fault | ||||||
|             case 0x0200BFF8: { // CLINT base, mtime reg |             return res; | ||||||
|                 uint64_t mtime = this->reg.icount >> 12 /*12*/; |  | ||||||
|                 std::copy((uint8_t *)&mtime, ((uint8_t *)&mtime) + length, data); |  | ||||||
|             } break; |  | ||||||
|             case 0x10008000: { |  | ||||||
|                 const mem_type::page_type &p = mem(paddr.val / mem.page_size); |  | ||||||
|                 uint64_t offs = paddr.val & mem.page_addr_mask; |  | ||||||
|                 std::copy(p.data() + offs, p.data() + offs + length, data); |  | ||||||
|                 if (this->reg.icount > 30000) data[3] |= 0x80; |  | ||||||
|             } break; |  | ||||||
|             default: { return read_mem(paddr, length, data); } |  | ||||||
|             } |  | ||||||
|         } catch (trap_access &ta) { |         } catch (trap_access &ta) { | ||||||
|             this->reg.trap_state = (1 << 31) | ta.id; |             this->reg.trap_state = (1 << 31) | ta.id; | ||||||
|             return iss::Err; |             return iss::Err; | ||||||
| @@ -677,6 +669,33 @@ iss::status riscv_hart_msu_vp<BASE>::write(const iss::addr_t &addr, unsigned len | |||||||
|     try { |     try { | ||||||
|         switch (addr.space) { |         switch (addr.space) { | ||||||
|         case traits<BASE>::MEM: { |         case traits<BASE>::MEM: { | ||||||
|  |             if ((addr.type & (iss::ACCESS_TYPE - iss::DEBUG)) == iss::FETCH && (addr.val & 0x1) == 1) { | ||||||
|  |                 fault_data = addr.val; | ||||||
|  |                 if ((addr.type & iss::DEBUG)) throw trap_access(0, addr.val); | ||||||
|  |                 this->reg.trap_state = (1 << 31); // issue trap 0 | ||||||
|  |                 return iss::Err; | ||||||
|  |             } | ||||||
|  |             try { | ||||||
|  |                 if ((addr.val & ~PGMASK) != ((addr.val + length - 1) & ~PGMASK)) { // we may cross a page boundary | ||||||
|  |                     vm_info vm = decode_vm_info<traits<BASE>::XLEN>(this->reg.machine_state, csr[satp]); | ||||||
|  |                     if (vm.levels != 0) { // VM is active | ||||||
|  |                         auto split_addr = (addr.val + length) & ~PGMASK; | ||||||
|  |                         auto len1 = split_addr - addr.val; | ||||||
|  |                         auto res = write(addr, len1, data); | ||||||
|  |                         if (res == iss::Ok) | ||||||
|  |                             res = write(iss::addr_t{addr.type, addr.space, split_addr}, length - len1, data + len1); | ||||||
|  |                         return res; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 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 | ||||||
|  |                 return res; | ||||||
|  |             } catch (trap_access &ta) { | ||||||
|  |                 this->reg.trap_state = (1 << 31) | ta.id; | ||||||
|  |                 return iss::Err; | ||||||
|  |             } | ||||||
|  |  | ||||||
|             phys_addr_t paddr = (addr.type & iss::ADDRESS_TYPE) == iss::PHYSICAL ? addr : v2p(addr); |             phys_addr_t paddr = (addr.type & iss::ADDRESS_TYPE) == iss::PHYSICAL ? addr : v2p(addr); | ||||||
|             if ((paddr.val + length) > mem.size()) return iss::Err; |             if ((paddr.val + length) > mem.size()) return iss::Err; | ||||||
|             switch (paddr.val) { |             switch (paddr.val) { | ||||||
| @@ -691,22 +710,22 @@ iss::status riscv_hart_msu_vp<BASE>::write(const iss::addr_t &addr, unsigned len | |||||||
|                 } |                 } | ||||||
|                 return iss::Ok; |                 return iss::Ok; | ||||||
|             case 0x10008000: { // HFROSC base, hfrosccfg reg |             case 0x10008000: { // HFROSC base, hfrosccfg reg | ||||||
|                 mem_type::page_type &p = mem(paddr.val / mem.page_size); |                 auto &p = mem(paddr.val / mem.page_size); | ||||||
|                 size_t offs = paddr.val & mem.page_addr_mask; |                 auto offs = paddr.val & mem.page_addr_mask; | ||||||
|                 std::copy(data, data + length, p.data() + offs); |                 std::copy(data, data + length, p.data() + offs); | ||||||
|                 uint8_t &x = *(p.data() + offs + 3); |                 auto &x = *(p.data() + offs + 3); | ||||||
|                 if (x & 0x40) x |= 0x80; // hfroscrdy = 1 if hfroscen==1 |                 if (x & 0x40) x |= 0x80; // hfroscrdy = 1 if hfroscen==1 | ||||||
|                 return iss::Ok; |                 return iss::Ok; | ||||||
|             } |             } | ||||||
|             case 0x10008008: { // HFROSC base, pllcfg reg |             case 0x10008008: { // HFROSC base, pllcfg reg | ||||||
|                 mem_type::page_type &p = mem(paddr.val / mem.page_size); |                 auto &p = mem(paddr.val / mem.page_size); | ||||||
|                 size_t offs = paddr.val & mem.page_addr_mask; |                 auto offs = paddr.val & mem.page_addr_mask; | ||||||
|                 std::copy(data, data + length, p.data() + offs); |                 std::copy(data, data + length, p.data() + offs); | ||||||
|                 uint8_t &x = *(p.data() + offs + 3); |                 auto &x = *(p.data() + offs + 3); | ||||||
|                 x |= 0x80; // set pll lock upon writing |                 x |= 0x80; // set pll lock upon writing | ||||||
|                 return iss::Ok; |                 return iss::Ok; | ||||||
|             } break; |             } break; | ||||||
|             default: { return write_mem(paddr, length, data); } |             default: {} | ||||||
|             } |             } | ||||||
|         } break; |         } break; | ||||||
|         case traits<BASE>::CSR: { |         case traits<BASE>::CSR: { | ||||||
| @@ -857,23 +876,67 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_satp(unsigne | |||||||
| } | } | ||||||
|  |  | ||||||
| template <typename BASE> | template <typename BASE> | ||||||
| iss::status riscv_hart_msu_vp<BASE>::read_mem(phys_addr_t addr, unsigned length, uint8_t *const data) { | iss::status riscv_hart_msu_vp<BASE>::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) { | ||||||
|     const auto &p = mem(addr.val / mem.page_size); |     if ((paddr.val + length) > mem.size()) return iss::Err; | ||||||
|     auto offs = addr.val & mem.page_addr_mask; |     switch (paddr.val) { | ||||||
|  |     case 0x0200BFF8: { // CLINT base, mtime reg | ||||||
|  |         uint64_t mtime = this->reg.icount >> 12 /*12*/; | ||||||
|  |         std::copy((uint8_t *)&mtime, ((uint8_t *)&mtime) + length, data); | ||||||
|  |     } break; | ||||||
|  |     case 0x10008000: { | ||||||
|  |         const mem_type::page_type &p = mem(paddr.val / mem.page_size); | ||||||
|  |         uint64_t offs = paddr.val & mem.page_addr_mask; | ||||||
|  |         std::copy(p.data() + offs, p.data() + offs + length, data); | ||||||
|  |         if (this->reg.icount > 30000) data[3] |= 0x80; | ||||||
|  |     } break; | ||||||
|  |     default: { | ||||||
|  |         const auto &p = mem(paddr.val / mem.page_size); | ||||||
|  |         auto offs = paddr.val & mem.page_addr_mask; | ||||||
|         std::copy(p.data() + offs, p.data() + offs + length, data); |         std::copy(p.data() + offs, p.data() + offs + length, data); | ||||||
|         return iss::Ok; |         return iss::Ok; | ||||||
|     } |     } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| template <typename BASE> | template <typename BASE> | ||||||
| iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t addr, unsigned length, const uint8_t *const data) { | iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t paddr, unsigned length, const uint8_t *const data) { | ||||||
|     mem_type::page_type &p = mem(addr.val / mem.page_size); |     if ((paddr.val + length) > mem.size()) return iss::Err; | ||||||
|     std::copy(data, data + length, p.data() + (addr.val & mem.page_addr_mask)); |     switch (paddr.val) { | ||||||
|  |     case 0x10013000: // UART0 base, TXFIFO reg | ||||||
|  |     case 0x10023000: // UART1 base, TXFIFO reg | ||||||
|  |         uart_buf << (char)data[0]; | ||||||
|  |         if (((char)data[0]) == '\n' || data[0] == 0) { | ||||||
|  |             // LOG(INFO)<<"UART"<<((paddr.val>>16)&0x3)<<" send | ||||||
|  |             // '"<<uart_buf.str()<<"'"; | ||||||
|  |             std::cout << uart_buf.str(); | ||||||
|  |             uart_buf.str(""); | ||||||
|  |         } | ||||||
|  |         return iss::Ok; | ||||||
|  |     case 0x10008000: { // HFROSC base, hfrosccfg reg | ||||||
|  |         mem_type::page_type &p = mem(paddr.val / mem.page_size); | ||||||
|  |         size_t offs = paddr.val & mem.page_addr_mask; | ||||||
|  |         std::copy(data, data + length, p.data() + offs); | ||||||
|  |         uint8_t &x = *(p.data() + offs + 3); | ||||||
|  |         if (x & 0x40) x |= 0x80; // hfroscrdy = 1 if hfroscen==1 | ||||||
|  |         return iss::Ok; | ||||||
|  |     } | ||||||
|  |     case 0x10008008: { // HFROSC base, pllcfg reg | ||||||
|  |         mem_type::page_type &p = mem(paddr.val / mem.page_size); | ||||||
|  |         size_t offs = paddr.val & mem.page_addr_mask; | ||||||
|  |         std::copy(data, data + length, p.data() + offs); | ||||||
|  |         uint8_t &x = *(p.data() + offs + 3); | ||||||
|  |         x |= 0x80; // set pll lock upon writing | ||||||
|  |         return iss::Ok; | ||||||
|  |     } break; | ||||||
|  |     default: { | ||||||
|  |         mem_type::page_type &p = mem(paddr.val / mem.page_size); | ||||||
|  |         std::copy(data, data + length, p.data() + (paddr.val & mem.page_addr_mask)); | ||||||
|         // tohost handling in case of riscv-test |         // tohost handling in case of riscv-test | ||||||
|     if ((addr.type & iss::DEBUG) == 0) { |         if ((paddr.type & iss::DEBUG) == 0) { | ||||||
|         auto tohost_upper = |             auto tohost_upper = (traits<BASE>::XLEN == 32 && paddr.val == (tohost + 4)) || | ||||||
|             (traits<BASE>::XLEN == 32 && addr.val == (tohost + 4)) || (traits<BASE>::XLEN == 64 && addr.val == tohost); |                                 (traits<BASE>::XLEN == 64 && paddr.val == tohost); | ||||||
|             auto tohost_lower = |             auto tohost_lower = | ||||||
|             (traits<BASE>::XLEN == 32 && addr.val == tohost) || (traits<BASE>::XLEN == 64 && addr.val == tohost); |                 (traits<BASE>::XLEN == 32 && paddr.val == tohost) || (traits<BASE>::XLEN == 64 && paddr.val == tohost); | ||||||
|             if (tohost_lower || tohost_upper) { |             if (tohost_lower || tohost_upper) { | ||||||
|                 uint64_t hostvar = *reinterpret_cast<uint64_t *>(p.data() + (tohost & mem.page_addr_mask)); |                 uint64_t hostvar = *reinterpret_cast<uint64_t *>(p.data() + (tohost & mem.page_addr_mask)); | ||||||
|                 if (tohost_upper || (tohost_lower && to_host_wr_cnt > 0)) { |                 if (tohost_upper || (tohost_lower && to_host_wr_cnt > 0)) { | ||||||
| @@ -900,14 +963,16 @@ iss::status riscv_hart_msu_vp<BASE>::write_mem(phys_addr_t addr, unsigned length | |||||||
|                     } |                     } | ||||||
|                 } else if (tohost_lower) |                 } else if (tohost_lower) | ||||||
|                     to_host_wr_cnt++; |                     to_host_wr_cnt++; | ||||||
|         } else if ((traits<BASE>::XLEN == 32 && addr.val == fromhost + 4) || |             } else if ((traits<BASE>::XLEN == 32 && paddr.val == fromhost + 4) || | ||||||
|                    (traits<BASE>::XLEN == 64 && addr.val == fromhost)) { |                        (traits<BASE>::XLEN == 64 && paddr.val == fromhost)) { | ||||||
|                 uint64_t fhostvar = *reinterpret_cast<uint64_t *>(p.data() + (fromhost & mem.page_addr_mask)); |                 uint64_t fhostvar = *reinterpret_cast<uint64_t *>(p.data() + (fromhost & mem.page_addr_mask)); | ||||||
|                 *reinterpret_cast<uint64_t *>(p.data() + (tohost & mem.page_addr_mask)) = fhostvar; |                 *reinterpret_cast<uint64_t *>(p.data() + (tohost & mem.page_addr_mask)) = fhostvar; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         return iss::Ok; |         return iss::Ok; | ||||||
|     } |     } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| template <typename BASE> void riscv_hart_msu_vp<BASE>::check_interrupt() { | template <typename BASE> void riscv_hart_msu_vp<BASE>::check_interrupt() { | ||||||
|     auto status = csr[mstatus]; |     auto status = csr[mstatus]; | ||||||
|   | |||||||
| @@ -140,7 +140,7 @@ struct rv32imac : public arch_if { | |||||||
|     using addr_t = typename traits<rv32imac>::addr_t; |     using addr_t = typename traits<rv32imac>::addr_t; | ||||||
|  |  | ||||||
|     rv32imac(); |     rv32imac(); | ||||||
|     ~rv32imac(); |     ~rv32imac() = default; | ||||||
|  |  | ||||||
|     void reset(uint64_t address = 0) override; |     void reset(uint64_t address = 0) override; | ||||||
|  |  | ||||||
| @@ -154,7 +154,7 @@ struct rv32imac : public arch_if { | |||||||
|     /// deprecated |     /// deprecated | ||||||
|     void update_flags(operations op, uint64_t opr1, uint64_t opr2) override{}; |     void update_flags(operations op, uint64_t opr1, uint64_t opr2) override{}; | ||||||
|  |  | ||||||
|     void notify_phase(exec_phase phase) { |     void notify_phase(exec_phase phase) override { | ||||||
|         if (phase == ISTART) { |         if (phase == ISTART) { | ||||||
|             ++reg.icount; |             ++reg.icount; | ||||||
|             reg.PC = reg.NEXT_PC; |             reg.PC = reg.NEXT_PC; | ||||||
|   | |||||||
| @@ -342,21 +342,8 @@ template <> | |||||||
| std::unique_ptr<vm_if> create<arch::CORE_DEF_NAME>(arch::CORE_DEF_NAME *core, unsigned short port, bool dump) { | std::unique_ptr<vm_if> create<arch::CORE_DEF_NAME>(arch::CORE_DEF_NAME *core, unsigned short port, bool dump) { | ||||||
|     std::unique_ptr<CORE_DEF_NAME::vm_impl<arch::CORE_DEF_NAME>> ret = |     std::unique_ptr<CORE_DEF_NAME::vm_impl<arch::CORE_DEF_NAME>> ret = | ||||||
|         std::make_unique<CORE_DEF_NAME::vm_impl<arch::CORE_DEF_NAME>>(*core, dump); |         std::make_unique<CORE_DEF_NAME::vm_impl<arch::CORE_DEF_NAME>>(*core, dump); | ||||||
|     debugger::server<debugger::gdb_session>::run_server(ret.get(), port); |     if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret.get(), port); | ||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
| template <> std::unique_ptr<vm_if> create<arch::CORE_DEF_NAME>(std::string inst_name, unsigned short port, bool dump) { |  | ||||||
|     return create<arch::CORE_DEF_NAME>(new arch::riscv_hart_msu_vp<arch::CORE_DEF_NAME>(), port, |  | ||||||
|                                        dump); /* FIXME: memory leak!!!!!!! */ |  | ||||||
| } |  | ||||||
|  |  | ||||||
| template <> std::unique_ptr<vm_if> create<arch::CORE_DEF_NAME>(arch::CORE_DEF_NAME *core, bool dump) { |  | ||||||
|     return std::make_unique<CORE_DEF_NAME::vm_impl<arch::CORE_DEF_NAME>>(*core, dump); /* FIXME: memory leak!!!!!!! */ |  | ||||||
| } |  | ||||||
|  |  | ||||||
| template <> std::unique_ptr<vm_if> create<arch::CORE_DEF_NAME>(std::string inst_name, bool dump) { |  | ||||||
|     return create<arch::CORE_DEF_NAME>(new arch::riscv_hart_msu_vp<arch::CORE_DEF_NAME>(), dump); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| } // namespace iss | } // namespace iss | ||||||
|   | |||||||
| @@ -4014,21 +4014,8 @@ template <typename ARCH> inline void vm_impl<ARCH>::gen_trap_check(llvm::BasicBl | |||||||
| template <> std::unique_ptr<vm_if> create<arch::rv32imac>(arch::rv32imac *core, unsigned short port, bool dump) { | template <> std::unique_ptr<vm_if> create<arch::rv32imac>(arch::rv32imac *core, unsigned short port, bool dump) { | ||||||
|     std::unique_ptr<rv32imac::vm_impl<arch::rv32imac>> ret = |     std::unique_ptr<rv32imac::vm_impl<arch::rv32imac>> ret = | ||||||
|         std::make_unique<rv32imac::vm_impl<arch::rv32imac>>(*core, dump); |         std::make_unique<rv32imac::vm_impl<arch::rv32imac>>(*core, dump); | ||||||
|     debugger::server<debugger::gdb_session>::run_server(ret.get(), port); |     if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret.get(), port); | ||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
| template <> std::unique_ptr<vm_if> create<arch::rv32imac>(std::string inst_name, unsigned short port, bool dump) { |  | ||||||
|     return create<arch::rv32imac>(new arch::riscv_hart_msu_vp<arch::rv32imac>(), port, |  | ||||||
|                                   dump); /* FIXME: memory leak!!!!!!! */ |  | ||||||
| } |  | ||||||
|  |  | ||||||
| template <> std::unique_ptr<vm_if> create<arch::rv32imac>(arch::rv32imac *core, bool dump) { |  | ||||||
|     return std::make_unique<rv32imac::vm_impl<arch::rv32imac>>(*core, dump); /* FIXME: memory leak!!!!!!! */ |  | ||||||
| } |  | ||||||
|  |  | ||||||
| template <> std::unique_ptr<vm_if> create<arch::rv32imac>(std::string inst_name, bool dump) { |  | ||||||
|     return create<arch::rv32imac>(new arch::riscv_hart_msu_vp<arch::rv32imac>(), dump); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| } // namespace iss | } // namespace iss | ||||||
|   | |||||||
| @@ -3101,21 +3101,8 @@ template <typename ARCH> inline void vm_impl<ARCH>::gen_trap_check(llvm::BasicBl | |||||||
|  |  | ||||||
| template <> std::unique_ptr<vm_if> create<arch::rv64ia>(arch::rv64ia *core, unsigned short port, bool dump) { | template <> std::unique_ptr<vm_if> create<arch::rv64ia>(arch::rv64ia *core, unsigned short port, bool dump) { | ||||||
|     std::unique_ptr<rv64ia::vm_impl<arch::rv64ia>> ret = std::make_unique<rv64ia::vm_impl<arch::rv64ia>>(*core, dump); |     std::unique_ptr<rv64ia::vm_impl<arch::rv64ia>> ret = std::make_unique<rv64ia::vm_impl<arch::rv64ia>>(*core, dump); | ||||||
|     debugger::server<debugger::gdb_session>::run_server(ret.get(), port); |     if (port != 0) debugger::server<debugger::gdb_session>::run_server(ret.get(), port); | ||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
| template <> std::unique_ptr<vm_if> create<arch::rv64ia>(std::string inst_name, unsigned short port, bool dump) { |  | ||||||
|     return create<arch::rv64ia>(new arch::riscv_hart_msu_vp<arch::rv64ia>(), port, |  | ||||||
|                                 dump); /* FIXME: memory leak!!!!!!! */ |  | ||||||
| } |  | ||||||
|  |  | ||||||
| template <> std::unique_ptr<vm_if> create<arch::rv64ia>(arch::rv64ia *core, bool dump) { |  | ||||||
|     return std::make_unique<rv64ia::vm_impl<arch::rv64ia>>(*core, dump); /* FIXME: memory leak!!!!!!! */ |  | ||||||
| } |  | ||||||
|  |  | ||||||
| template <> std::unique_ptr<vm_if> create<arch::rv64ia>(std::string inst_name, bool dump) { |  | ||||||
|     return create<arch::rv64ia>(new arch::riscv_hart_msu_vp<arch::rv64ia>(), dump); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| } // namespace iss | } // namespace iss | ||||||
|   | |||||||
| @@ -54,8 +54,6 @@ using namespace iss::arch; | |||||||
|  |  | ||||||
| rv32imac::rv32imac() { reg.icount = 0; } | rv32imac::rv32imac() { reg.icount = 0; } | ||||||
|  |  | ||||||
| rv32imac::~rv32imac() {} |  | ||||||
|  |  | ||||||
| void rv32imac::reset(uint64_t address) { | void rv32imac::reset(uint64_t address) { | ||||||
|     for (size_t i = 0; i < traits<rv32imac>::NUM_REGS; ++i) |     for (size_t i = 0; i < traits<rv32imac>::NUM_REGS; ++i) | ||||||
|         set_reg(i, std::vector<uint8_t>(sizeof(traits<rv32imac>::reg_t), 0)); |         set_reg(i, std::vector<uint8_t>(sizeof(traits<rv32imac>::reg_t), 0)); | ||||||
|   | |||||||
| @@ -32,11 +32,12 @@ | |||||||
| //       eyck@minres.com - initial API and implementation | //       eyck@minres.com - initial API and implementation | ||||||
| //////////////////////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////////////////////// | ||||||
|  |  | ||||||
| #include <cli_options.h> |  | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <iss/iss.h> | #include <iss/iss.h> | ||||||
|  |  | ||||||
| #include <boost/lexical_cast.hpp> | #include <boost/lexical_cast.hpp> | ||||||
|  | #include <boost/program_options.hpp> | ||||||
|  | #include <iss/arch/riscv_hart_msu_vp.h> | ||||||
| #include <iss/arch/rv32imac.h> | #include <iss/arch/rv32imac.h> | ||||||
| #include <iss/arch/rv64ia.h> | #include <iss/arch/rv64ia.h> | ||||||
| #include <iss/jit/MCJIThelper.h> | #include <iss/jit/MCJIThelper.h> | ||||||
| @@ -45,69 +46,97 @@ | |||||||
| namespace po = boost::program_options; | namespace po = boost::program_options; | ||||||
|  |  | ||||||
| int main(int argc, char *argv[]) { | int main(int argc, char *argv[]) { | ||||||
|     try { |  | ||||||
|     /* |     /* | ||||||
|      *  Define and parse the program options |      *  Define and parse the program options | ||||||
|      */ |      */ | ||||||
|         po::variables_map vm; |     po::variables_map clim; | ||||||
|         if (parse_cli_options(vm, argc, argv)) return ERROR_IN_COMMAND_LINE; |     po::options_description desc("Options"); | ||||||
|         if (vm.count("verbose")) { |     // clang-format off | ||||||
|             auto l = logging::as_log_level(vm["verbose"].as<int>()); |     desc.add_options() | ||||||
|  |         ("help,h", "Print help message") | ||||||
|  |         ("verbose,v", po::value<int>()->implicit_value(0), "Sets logging verbosity") | ||||||
|  |         ("log-file", po::value<std::string>(), "Sets default log file.") | ||||||
|  |         ("disass,d", po::value<std::string>()->implicit_value(""), "Enables disassembly") | ||||||
|  |         ("elf,l", po::value<std::vector<std::string>>(), "ELF file(s) to load") | ||||||
|  |         ("gdb-port,g", po::value<unsigned>()->default_value(0), "enable gdb server and specify port to use") | ||||||
|  |         ("input,i", po::value<std::string>(), "the elf file to load (instead of hex files)") | ||||||
|  |         ("dump-ir", "dump the intermediate representation") | ||||||
|  |         ("cycles,c", po::value<int64_t>()->default_value(-1), "number of cycles to run") | ||||||
|  |         ("systemc,s", "Run as SystemC simulation") | ||||||
|  |         ("time", po::value<int>(), "SystemC siimulation time in ms") | ||||||
|  |         ("reset,r", po::value<std::string>(), "reset address") | ||||||
|  |         ("trace", po::value<uint8_t>(), "enable tracing, or cmbintation of 1=signals and 2=TX text, 4=TX compressed text, 6=TX in SQLite") | ||||||
|  |         ("mem,m", po::value<std::string>(), "the memory input file") | ||||||
|  |         ("rv64", "run RV64"); | ||||||
|  |     // clang-format on | ||||||
|  |     try { | ||||||
|  |         po::store(po::parse_command_line(argc, argv, desc), clim); // can throw | ||||||
|  |         // --help option | ||||||
|  |         if (clim.count("help")) { | ||||||
|  |             std::cout << "DBT-RISE-RiscV simulator for RISC-V" << std::endl << desc << std::endl; | ||||||
|  |             return 0; | ||||||
|  |         } | ||||||
|  |         po::notify(clim); // throws on error, so do after help in case | ||||||
|  |     } catch (po::error &e) { | ||||||
|  |         // there are problems | ||||||
|  |         std::cerr << "ERROR: " << e.what() << std::endl << std::endl; | ||||||
|  |         std::cerr << desc << std::endl; | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  |     if (clim.count("verbose")) { | ||||||
|  |         auto l = logging::as_log_level(clim["verbose"].as<int>()); | ||||||
|         LOGGER(DEFAULT)::reporting_level() = l; |         LOGGER(DEFAULT)::reporting_level() = l; | ||||||
|         LOGGER(connection)::reporting_level() = l; |         LOGGER(connection)::reporting_level() = l; | ||||||
|     } |     } | ||||||
|         if (vm.count("log-file")) { |     if (clim.count("log-file")) { | ||||||
|         // configure the connection logger |         // configure the connection logger | ||||||
|             auto f = fopen(vm["log-file"].as<std::string>().c_str(), "w"); |         auto f = fopen(clim["log-file"].as<std::string>().c_str(), "w"); | ||||||
|         LOG_OUTPUT(DEFAULT)::stream() = f; |         LOG_OUTPUT(DEFAULT)::stream() = f; | ||||||
|         LOG_OUTPUT(connection)::stream() = f; |         LOG_OUTPUT(connection)::stream() = f; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     try { | ||||||
|         // application code comes here // |         // application code comes here // | ||||||
|         iss::init_jit(argc, argv); |         iss::init_jit(argc, argv); | ||||||
|         bool dump = vm.count("dump-ir"); |         bool dump = clim.count("dump-ir"); | ||||||
|         // instantiate the simulator |         // instantiate the simulator | ||||||
|         std::unique_ptr<iss::vm_if> cpu{nullptr}; |         std::unique_ptr<iss::vm_if> vm{nullptr}; | ||||||
|         if (vm.count("rv64") == 1) { |         if (clim.count("rv64") == 1) { | ||||||
|             if (vm.count("gdb-port") == 1) |             auto cpu = new iss::arch::riscv_hart_msu_vp<iss::arch::rv64ia>(); | ||||||
|                 cpu = iss::create<iss::arch::rv64ia>("rv64ia", vm["gdb-port"].as<unsigned>(), dump); |             vm = iss::create<iss::arch::rv64ia>(cpu, clim["gdb-port"].as<unsigned>(), dump); | ||||||
|             else |  | ||||||
|                 cpu = iss::create<iss::arch::rv64ia>("rv64ia", dump); |  | ||||||
|         } else { |         } else { | ||||||
|             if (vm.count("gdb-port") == 1) |             auto cpu = new iss::arch::riscv_hart_msu_vp<iss::arch::rv32imac>(); | ||||||
|                 cpu = iss::create<iss::arch::rv32imac>("rv32ima", vm["gdb-port"].as<unsigned>(), dump); |             vm = iss::create<iss::arch::rv32imac>(cpu, clim["gdb-port"].as<unsigned>(), dump); | ||||||
|             else |  | ||||||
|                 cpu = iss::create<iss::arch::rv32imac>("rv32ima", dump); |  | ||||||
|         } |         } | ||||||
|         if (vm.count("elf")) { |         if (clim.count("elf")) { | ||||||
|             for (std::string input : vm["elf"].as<std::vector<std::string>>()) cpu->get_arch()->load_file(input); |             for (std::string input : clim["elf"].as<std::vector<std::string>>()) vm->get_arch()->load_file(input); | ||||||
|         } else if (vm.count("mem")) { |         } else if (clim.count("mem")) { | ||||||
|             cpu->get_arch()->load_file(vm["mem"].as<std::string>(), iss::arch::traits<iss::arch::rv32imac>::MEM); |             vm->get_arch()->load_file(clim["mem"].as<std::string>(), iss::arch::traits<iss::arch::rv32imac>::MEM); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (vm.count("disass")) { |         if (clim.count("disass")) { | ||||||
|             cpu->setDisassEnabled(true); |             vm->setDisassEnabled(true); | ||||||
|             LOGGER(disass)::reporting_level() = logging::INFO; |             LOGGER(disass)::reporting_level() = logging::INFO; | ||||||
|             auto file_name = vm["disass"].as<std::string>(); |             auto file_name = clim["disass"].as<std::string>(); | ||||||
|             if (file_name.length() > 0) { |             if (file_name.length() > 0) { | ||||||
|                 LOG_OUTPUT(disass)::stream() = fopen(file_name.c_str(), "w"); |                 LOG_OUTPUT(disass)::stream() = fopen(file_name.c_str(), "w"); | ||||||
|                 LOGGER(disass)::print_time() = false; |                 LOGGER(disass)::print_time() = false; | ||||||
|                 LOGGER(disass)::print_severity() = false; |                 LOGGER(disass)::print_severity() = false; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         if (vm.count("reset")) { |         if (clim.count("reset")) { | ||||||
|             auto str = vm["reset"].as<std::string>(); |             auto str = clim["reset"].as<std::string>(); | ||||||
|             auto start_address = str.find("0x") == 0 ? std::stoull(str, 0, 16) : std::stoull(str, 0, 10); |             auto start_address = str.find("0x") == 0 ? std::stoull(str.substr(2), 0, 16) : std::stoull(str, 0, 10); | ||||||
|             cpu->reset(start_address); |             vm->reset(start_address); | ||||||
|         } else { |         } else { | ||||||
|             cpu->reset(); |             vm->reset(); | ||||||
|         } |         } | ||||||
|         int64_t cycles = -1; |         int64_t cycles = -1; | ||||||
|         cycles = vm["cycles"].as<int64_t>(); |         cycles = clim["cycles"].as<int64_t>(); | ||||||
|         return cpu->start(cycles); |         return vm->start(cycles); | ||||||
|     } catch (std::exception &e) { |     } catch (std::exception &e) { | ||||||
|         LOG(ERROR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit" |         LOG(ERROR) << "Unhandled Exception reached the top of main: " << e.what() << ", application will now exit" | ||||||
|                    << std::endl; |                    << std::endl; | ||||||
|         return ERROR_UNHANDLED_EXCEPTION; |         return 2; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
 Submodule sc-components updated: 3693b05536...35379b77b6
									
								
							
		Reference in New Issue
	
	Block a user