diff --git a/.cproject b/.cproject index 67a12ff..04b9909 100644 --- a/.cproject +++ b/.cproject @@ -72,7 +72,7 @@ - @@ -155,7 +155,7 @@ - diff --git a/.gitignore b/.gitignore index a3c39fc..2865d22 100644 --- a/.gitignore +++ b/.gitignore @@ -6,28 +6,27 @@ /avr-gdb.cmd /main.cpp /Debug/ -/Reelease/ /core /*.launch /*.csv /Release/ /*.vcd /*.ods -/build/ +/build*/ /*.logs language.settings.xml /*.gtkw /Debug wo LLVM/ -/atmega.txdb -/atmega.txlgz -/atmega.txlog +/*.txdb +/*.txlgz +/*.txlog /.??*bdb.d.0 /.??*bdb.i.0 /.??*bdb.t /tmp/ -/test1.elf +/*.elf /logs/ /*.log /.gdbinit /*.out -/*.txlog +/dump.json diff --git a/README.md b/README.md index fe8cef5..9c0d7a8 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,8 @@ DBT-RISE-RiscV uses libGIS (https://github.com/vsergeev/libGIS) as well as ELFIO **What's missing** -* RV64I is only preliminary verified -* F & D standard extensions to be implemented +* F & D standard extensions for 32bit to be implemented +* MACF &D standard extensions for 64bit to be implemented and verified **Planned features** diff --git a/dbt-core b/dbt-core index 3b05de8..d0422e5 160000 --- a/dbt-core +++ b/dbt-core @@ -1 +1 @@ -Subproject commit 3b05de8c14f5d7b5d1ff55f5f244f797992be83d +Subproject commit d0422e5f8df2391df372779b06c807d456a058a3 diff --git a/html/ws.html b/html/ws.html index b3b0441..56edd32 100644 --- a/html/ws.html +++ b/html/ws.html @@ -11,8 +11,9 @@ li { font-family: Courier; list-style-type: '>';} pre { margin-top:0; margin-bottom:0;} .term { background-color:black; color:white; font-weight:bold;padding-top:10px; padding-bottom:10px; max-height:400px; overflow: scroll;} span.timestamp { font-family: monospace; white-space: pre;width: 50px;} +span.value_z { background-color: darkblue;} span.value_1 { background-color: green;} -span.value_0 { background-color: blue;} +span.value_0 { background-color: yellow;} span.value_x { background-color: red;} diff --git a/riscv.sc/incl/sysc/SiFive/aon.h b/riscv.sc/incl/sysc/SiFive/aon.h index 62afa03..4173def 100644 --- a/riscv.sc/incl/sysc/SiFive/aon.h +++ b/riscv.sc/incl/sysc/SiFive/aon.h @@ -1,18 +1,38 @@ -/******************************************************************************* - * 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. - ******************************************************************************/ +//////////////////////////////////////////////////////////////////////////////// +// 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 implementation +// +// +//////////////////////////////////////////////////////////////////////////////// #ifndef _AON_H_ #define _AON_H_ diff --git a/riscv.sc/incl/sysc/SiFive/clint.h b/riscv.sc/incl/sysc/SiFive/clint.h index 1e3fbf1..c4001d5 100644 --- a/riscv.sc/incl/sysc/SiFive/clint.h +++ b/riscv.sc/incl/sysc/SiFive/clint.h @@ -1,18 +1,38 @@ -/******************************************************************************* - * 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. - ******************************************************************************/ +//////////////////////////////////////////////////////////////////////////////// +// 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 implementation +// +// +//////////////////////////////////////////////////////////////////////////////// #ifndef _CLINT_H_ #define _CLINT_H_ diff --git a/riscv.sc/incl/sysc/SiFive/core_complex.h b/riscv.sc/incl/sysc/SiFive/core_complex.h index 41a1042..24f5b1f 100644 --- a/riscv.sc/incl/sysc/SiFive/core_complex.h +++ b/riscv.sc/incl/sysc/SiFive/core_complex.h @@ -29,7 +29,7 @@ // POSSIBILITY OF SUCH DAMAGE. // // Contributors: -// eyck@minres.com - initial API and implementation +// eyck@minres.com - initial implementation // // //////////////////////////////////////////////////////////////////////////////// diff --git a/riscv.sc/incl/sysc/SiFive/gpio.h b/riscv.sc/incl/sysc/SiFive/gpio.h index 9bc0b7b..3d03681 100644 --- a/riscv.sc/incl/sysc/SiFive/gpio.h +++ b/riscv.sc/incl/sysc/SiFive/gpio.h @@ -1,23 +1,44 @@ -/******************************************************************************* - * 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. - ******************************************************************************/ +//////////////////////////////////////////////////////////////////////////////// +// 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 implementation +// +// +//////////////////////////////////////////////////////////////////////////////// #ifndef _GPIO_H_ #define _GPIO_H_ #include "scc/tlm_target.h" +#include "scc/ext_attribute.h" #include namespace sysc { @@ -35,11 +56,13 @@ public: gpio(sc_core::sc_module_name nm); virtual ~gpio() override; // need to keep it in source file because of fwd declaration of gpio_regs + scc::ext_attribute write_to_ws; protected: void clock_cb(); void reset_cb(); void update_pins(); void pins_cb(); + void before_end_of_elaboration(); sc_core::sc_time clk; std::unique_ptr regs; std::shared_ptr handler; diff --git a/riscv.sc/incl/sysc/SiFive/platform.h b/riscv.sc/incl/sysc/SiFive/platform.h index efdb74d..9055c43 100644 --- a/riscv.sc/incl/sysc/SiFive/platform.h +++ b/riscv.sc/incl/sysc/SiFive/platform.h @@ -1,24 +1,38 @@ -/******************************************************************************* - * 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. - ******************************************************************************/ -/* - * simplesystem.h - * - * Created on: 17.09.2017 - * Author: eyck@minres.com - */ +//////////////////////////////////////////////////////////////////////////////// +// 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 implementation +// +// +//////////////////////////////////////////////////////////////////////////////// #ifndef SIMPLESYSTEM_H_ #define SIMPLESYSTEM_H_ diff --git a/riscv.sc/incl/sysc/SiFive/plic.h b/riscv.sc/incl/sysc/SiFive/plic.h index 93d3b87..60ee500 100644 --- a/riscv.sc/incl/sysc/SiFive/plic.h +++ b/riscv.sc/incl/sysc/SiFive/plic.h @@ -1,18 +1,38 @@ -/******************************************************************************* - * 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. - ******************************************************************************/ +//////////////////////////////////////////////////////////////////////////////// +// 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 implementation +// +// +//////////////////////////////////////////////////////////////////////////////// #ifndef _PLIC_H_ #define _PLIC_H_ diff --git a/riscv.sc/incl/sysc/SiFive/prci.h b/riscv.sc/incl/sysc/SiFive/prci.h index 463cb58..da854c3 100644 --- a/riscv.sc/incl/sysc/SiFive/prci.h +++ b/riscv.sc/incl/sysc/SiFive/prci.h @@ -1,18 +1,38 @@ -/******************************************************************************* - * 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. - ******************************************************************************/ +//////////////////////////////////////////////////////////////////////////////// +// 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 implementation +// +// +//////////////////////////////////////////////////////////////////////////////// #ifndef _PRCI_H_ #define _PRCI_H_ diff --git a/riscv.sc/incl/sysc/SiFive/spi.h b/riscv.sc/incl/sysc/SiFive/spi.h index 78ae7df..5d0ec2a 100644 --- a/riscv.sc/incl/sysc/SiFive/spi.h +++ b/riscv.sc/incl/sysc/SiFive/spi.h @@ -1,18 +1,38 @@ -/******************************************************************************* - * 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. - ******************************************************************************/ +//////////////////////////////////////////////////////////////////////////////// +// 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 implementation +// +// +//////////////////////////////////////////////////////////////////////////////// #ifndef _SPI_H_ #define _SPI_H_ diff --git a/riscv.sc/incl/sysc/SiFive/uart.h b/riscv.sc/incl/sysc/SiFive/uart.h index 095f9d4..4052d61 100644 --- a/riscv.sc/incl/sysc/SiFive/uart.h +++ b/riscv.sc/incl/sysc/SiFive/uart.h @@ -1,22 +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. - ******************************************************************************/ +//////////////////////////////////////////////////////////////////////////////// +// 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 implementation +// +// +//////////////////////////////////////////////////////////////////////////////// #ifndef _UART_H_ #define _UART_H_ +#include "scc/ext_attribute.h" #include "scc/tlm_target.h" namespace sysc { @@ -32,10 +53,12 @@ public: uart(sc_core::sc_module_name nm); virtual ~uart() override; + scc::ext_attribute write_to_ws; protected: void clock_cb(); void reset_cb(); void transmit_data(); + void before_end_of_elaboration(); sc_core::sc_time clk; std::unique_ptr regs; std::vector queue; diff --git a/riscv.sc/incl/sysc/sc_comm_singleton.h b/riscv.sc/incl/sysc/sc_comm_singleton.h index d6c4aa9..9f41321 100644 --- a/riscv.sc/incl/sysc/sc_comm_singleton.h +++ b/riscv.sc/incl/sysc/sc_comm_singleton.h @@ -1,9 +1,38 @@ -/* - * sc_singleton.h - * - * Created on: 09.10.2017 - * Author: eyck - */ +//////////////////////////////////////////////////////////////////////////////// +// 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 implementation +// +// +//////////////////////////////////////////////////////////////////////////////// #ifndef RISCV_SC_INCL_SYSC_SC_COMM_SINGLETON_H_ #define RISCV_SC_INCL_SYSC_SC_COMM_SINGLETON_H_ @@ -75,7 +104,8 @@ private: std::unique_ptr m_serv; std::thread t; void thread_func(); - bool client_started; + bool needs_client, client_started; + std::vector endpoints; }; } /* namespace sysc */ diff --git a/riscv.sc/src/sc_main.cpp b/riscv.sc/src/sc_main.cpp index 5e5e076..6a7230d 100644 --- a/riscv.sc/src/sc_main.cpp +++ b/riscv.sc/src/sc_main.cpp @@ -1,24 +1,38 @@ //////////////////////////////////////////////////////////////////////////////// -// Copyright 2017 eyck@minres.com +// Copyright (C) 2017, MINRES Technologies GmbH +// All rights reserved. // -// 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 +// 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 implementation // -// 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. //////////////////////////////////////////////////////////////////////////////// -/* - * sc_main.cpp - * - * Created on: 17.09.2017 - * Author: eyck@minres.com - */ #include #include @@ -61,7 +75,8 @@ int sc_main(int argc, char *argv[]) { ("reset,r", po::value(), "reset address") ("trace,t", po::value()->default_value(0), "enable tracing, or combintation of 1=signals and 2=TX text, 4=TX compressed text, 6=TX in SQLite") ("max_time,m", po::value(), "maximum time to run") - ("config-file,c", po::value()->default_value(""), "configuration file"); + ("config-file,c", po::value()->default_value(""), "read configuration from file") + ("dump-config", po::value()->default_value(""), "dump configuration to file file"); // clang-format on po::variables_map vm; try { @@ -111,8 +126,21 @@ int sc_main(int argc, char *argv[]) { platform i_simple_system("i_simple_system"); // sr_report_handler::add_sc_object_to_filter(&i_simple_system.i_master, // 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()); + if (vm.count("dump-config")){ + std::ofstream of{vm["dump-config"].as()}; + if(of.is_open()) + cfg.dump_configuration(of); + } + cfg.configure(); + // overwrite with command line settings + if (vm.count("gdb-port")) + cfg.set_value("i_simple_system.i_core_complex.gdb_server_port", vm["gdb-port"].as()); + if (vm.count("dump-ir")) + cfg.set_value("i_simple_system.i_core_complex.dump_ir", vm.count("dump-ir") != 0); + if (vm.count("elf")) + cfg.set_value("i_simple_system.i_core_complex.elf_file", vm["elf"].as()); + if (vm.count("quantum")) + tlm::tlm_global_quantum::instance().set(sc_core::sc_time(vm["quantum"].as(), sc_core::SC_NS)); if (vm.count("reset")) { auto str = vm["reset"].as(); uint64_t start_address = str.find("0x") == 0 ? std::stoull(str.substr(2), 0, 16) : std::stoull(str, 0, 10); @@ -128,11 +156,6 @@ int sc_main(int argc, char *argv[]) { LOGGER(disass)::print_severity() = false; } } - cfg.set_value("i_simple_system.i_core_complex.gdb_server_port", vm["gdb-port"].as()); - 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(), sc_core::SC_NS)); - } /////////////////////////////////////////////////////////////////////////// // run simulation /////////////////////////////////////////////////////////////////////////// diff --git a/riscv.sc/src/sysc/aon.cpp b/riscv.sc/src/sysc/aon.cpp index 62cf859..454930a 100644 --- a/riscv.sc/src/sysc/aon.cpp +++ b/riscv.sc/src/sysc/aon.cpp @@ -1,17 +1,37 @@ //////////////////////////////////////////////////////////////////////////////// -// Copyright 2017 eyck@minres.com +// Copyright (C) 2017, MINRES Technologies GmbH +// All rights reserved. // -// 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 +// 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 implementation // -// 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" diff --git a/riscv.sc/src/sysc/clint.cpp b/riscv.sc/src/sysc/clint.cpp index a99595b..fffcf20 100644 --- a/riscv.sc/src/sysc/clint.cpp +++ b/riscv.sc/src/sysc/clint.cpp @@ -1,17 +1,37 @@ //////////////////////////////////////////////////////////////////////////////// -// Copyright 2017 eyck@minres.com +// Copyright (C) 2017, MINRES Technologies GmbH +// All rights reserved. // -// 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 +// 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 implementation // -// 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" diff --git a/riscv.sc/src/sysc/core_complex.cpp b/riscv.sc/src/sysc/core_complex.cpp index 36acdd3..a3f48c8 100644 --- a/riscv.sc/src/sysc/core_complex.cpp +++ b/riscv.sc/src/sysc/core_complex.cpp @@ -29,7 +29,7 @@ // POSSIBILITY OF SUCH DAMAGE. // // Contributors: -// eyck@minres.com - initial API and implementation +// eyck@minres.com - initial implementation // // //////////////////////////////////////////////////////////////////////////////// @@ -279,6 +279,7 @@ void core_complex::disass_output(uint64_t pc, const std::string instr_str) { tr_handle.record_attribute("INSTR", instr_str); tr_handle.record_attribute("MODE", lvl[cpu->get_mode()]); tr_handle.record_attribute("MSTATUS", cpu->get_state().mstatus.st.value); + tr_handle.record_attribute("LTIME_START", quantum_keeper.get_current_time().value()/1000); #endif } @@ -326,7 +327,9 @@ bool core_complex::read_mem(uint64_t addr, unsigned length, uint8_t *const data, auto delay{quantum_keeper.get_local_time()}; #ifdef WITH_SCV if(m_db!=nullptr && tr_handle.is_valid()){ - if(is_fetch && tr_handle.is_active()) tr_handle.end_transaction(); + if(is_fetch && tr_handle.is_active()){ + tr_handle.end_transaction(); + } auto preExt = new scv4tlm::tlm_recording_extension(tr_handle, this); gp.set_extension(preExt); } @@ -371,6 +374,12 @@ bool core_complex::write_mem(uint64_t addr, unsigned length, const uint8_t *cons gp.set_data_length(length); gp.set_streaming_width(length); auto delay{quantum_keeper.get_local_time()}; +#ifdef WITH_SCV + if(m_db!=nullptr && tr_handle.is_valid()){ + auto preExt = new scv4tlm::tlm_recording_extension(tr_handle, this); + gp.set_extension(preExt); + } +#endif initiator->b_transport(gp, delay); quantum_keeper.set(delay); LOG(TRACE) << "write_mem(0x" << std::hex << addr << ") : " << data; diff --git a/riscv.sc/src/sysc/gpio.cpp b/riscv.sc/src/sysc/gpio.cpp index 2b761e0..a0a41db 100644 --- a/riscv.sc/src/sysc/gpio.cpp +++ b/riscv.sc/src/sysc/gpio.cpp @@ -1,17 +1,37 @@ //////////////////////////////////////////////////////////////////////////////// -// Copyright 2017 eyck@minres.com +// Copyright (C) 2017, MINRES Technologies GmbH +// All rights reserved. // -// 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 +// 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 implementation // -// 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/gpio.h" @@ -29,7 +49,8 @@ gpio::gpio(sc_core::sc_module_name nm) , NAMED(clk_i) , NAMED(rst_i) , NAMED(pins_io) -, NAMEDD(gpio_regs, regs) { +, NAMEDD(gpio_regs, regs) +, NAMED(write_to_ws, false, this){ regs->registerResources(*this); SC_METHOD(clock_cb); sensitive << clk_i; @@ -56,14 +77,18 @@ gpio::gpio(sc_core::sc_module_name nm) } return true; }); - LOG(TRACE)<<"Adding WS handler for "<<(std::string{"/ws/"}+name()); - handler=std::make_shared(); - sc_comm_singleton::inst().registerWebSocketHandler((std::string{"/ws/"}+name()).c_str(), handler); - } gpio::~gpio() {} +void gpio::before_end_of_elaboration() { + if(write_to_ws.value) { + LOG(TRACE)<<"Adding WS handler for "<<(std::string{"/ws/"}+name()); + handler=std::make_shared(); + sc_comm_singleton::inst().registerWebSocketHandler((std::string{"/ws/"}+name()).c_str(), handler); + } +} + void gpio::reset_cb() { if (rst_i.read()) regs->reset_start(); @@ -79,9 +104,8 @@ void gpio::pins_cb(){ auto inval=pins_io.read(); std::string msg(inval.to_string()); sc_core::sc_time now = sc_core::sc_time_stamp(); - sc_comm_singleton::inst().execute([this, msg, now](){ + if(handler) sc_comm_singleton::inst().execute([this, msg, now](){ std::stringstream os; - //os << "[" << std::setw(20) << now << "] "<handler->send(os.str()); }); diff --git a/riscv.sc/src/sysc/platform.cpp b/riscv.sc/src/sysc/platform.cpp index 315fedc..40d1e9d 100644 --- a/riscv.sc/src/sysc/platform.cpp +++ b/riscv.sc/src/sysc/platform.cpp @@ -1,24 +1,38 @@ //////////////////////////////////////////////////////////////////////////////// -// Copyright 2017 eyck@minres.com +// Copyright (C) 2017, MINRES Technologies GmbH +// All rights reserved. // -// 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 +// 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 implementation // -// 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. //////////////////////////////////////////////////////////////////////////////// -/* - * simplesystem.cpp - * - * Created on: 17.09.2017 - * Author: eyck@minres.com - */ #include diff --git a/riscv.sc/src/sysc/plic.cpp b/riscv.sc/src/sysc/plic.cpp index 3ff41c3..1cfb0e7 100644 --- a/riscv.sc/src/sysc/plic.cpp +++ b/riscv.sc/src/sysc/plic.cpp @@ -1,17 +1,37 @@ //////////////////////////////////////////////////////////////////////////////// -// Copyright 2017 eyck@minres.com +// Copyright (C) 2017, MINRES Technologies GmbH +// All rights reserved. // -// 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 +// 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 implementation // -// 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 diff --git a/riscv.sc/src/sysc/prci.cpp b/riscv.sc/src/sysc/prci.cpp index 0ce0374..363def0 100644 --- a/riscv.sc/src/sysc/prci.cpp +++ b/riscv.sc/src/sysc/prci.cpp @@ -1,17 +1,37 @@ //////////////////////////////////////////////////////////////////////////////// -// Copyright 2017 eyck@minres.com +// Copyright (C) 2017, MINRES Technologies GmbH +// All rights reserved. // -// 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 +// 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 implementation // -// 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" diff --git a/riscv.sc/src/sysc/sc_comm_singleton.cpp b/riscv.sc/src/sysc/sc_comm_singleton.cpp index 73a474c..5f85ad9 100644 --- a/riscv.sc/src/sysc/sc_comm_singleton.cpp +++ b/riscv.sc/src/sysc/sc_comm_singleton.cpp @@ -1,9 +1,38 @@ -/* - * sc_singleton.cpp - * - * Created on: 09.10.2017 - * Author: eyck - */ +//////////////////////////////////////////////////////////////////////////////// +// 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 implementation +// +// +//////////////////////////////////////////////////////////////////////////////// #include "sysc/sc_comm_singleton.h" @@ -35,6 +64,7 @@ inline void die(){perror(nullptr);exit(errno);} sc_comm_singleton::sc_comm_singleton(sc_core::sc_module_name nm) : sc_core::sc_module(nm) , m_serv(new Server(std::make_shared(Logger::Level::WARNING))) +, needs_client(false) , client_started(false){ m_serv->addPageHandler(std::make_shared(*this)); } @@ -47,7 +77,7 @@ sc_comm_singleton::~sc_comm_singleton() { void sc_comm_singleton::start_of_simulation() { //Launch a thread t=std::thread(&sc_comm_singleton::thread_func, this); - start_client(); + if(needs_client) start_client(); } void sc_comm_singleton::end_of_simulation() { @@ -112,6 +142,8 @@ void sc_comm_singleton::registerWebSocketHandler(const char* endpoint, std::shared_ptr handler, bool allowCrossOriginRequests) { get_server().addWebSocketHandler(endpoint, handler, allowCrossOriginRequests); + endpoints.push_back(endpoint); + needs_client=true; } void sc_comm_singleton::execute(std::function f) { @@ -136,7 +168,6 @@ std::shared_ptr sc_comm_singleton::DefaultPageHandler::handle(const Re void WsHandler::onConnect(WebSocket* connection) { _connections.insert(connection); - //connection->send("Connection established");; } void WsHandler::onData(WebSocket* connection, const char* data) { diff --git a/riscv.sc/src/sysc/spi.cpp b/riscv.sc/src/sysc/spi.cpp index 53671e5..cb4b79d 100644 --- a/riscv.sc/src/sysc/spi.cpp +++ b/riscv.sc/src/sysc/spi.cpp @@ -1,17 +1,37 @@ //////////////////////////////////////////////////////////////////////////////// -// Copyright 2017 eyck@minres.com +// Copyright (C) 2017, MINRES Technologies GmbH +// All rights reserved. // -// 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 +// 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 implementation // -// 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/spi.h" diff --git a/riscv.sc/src/sysc/uart.cpp b/riscv.sc/src/sysc/uart.cpp index 2176a32..9031f2e 100644 --- a/riscv.sc/src/sysc/uart.cpp +++ b/riscv.sc/src/sysc/uart.cpp @@ -1,17 +1,37 @@ //////////////////////////////////////////////////////////////////////////////// -// Copyright 2017 eyck@minres.com +// Copyright (C) 2017, MINRES Technologies GmbH +// All rights reserved. // -// 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 +// 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 implementation // -// 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/uart.h" @@ -36,7 +56,8 @@ uart::uart(sc_core::sc_module_name nm) , tlm_target<>(clk) , NAMED(clk_i) , NAMED(rst_i) -, NAMEDD(uart_regs, regs) { +, NAMEDD(uart_regs, regs) +, NAMED(write_to_ws, false, this) { regs->registerResources(*this); SC_METHOD(clock_cb); sensitive << clk_i; @@ -50,13 +71,18 @@ uart::uart(sc_core::sc_module_name nm) } return true; }); - LOG(TRACE)<<"Adding WS handler for "<<(std::string{"/ws/"}+name()); - handler=std::make_shared(); - sc_comm_singleton::inst().registerWebSocketHandler((std::string{"/ws/"}+name()).c_str(), handler); } uart::~uart() {} +void uart::before_end_of_elaboration() { + if(write_to_ws.value) { + LOG(TRACE)<<"Adding WS handler for "<<(std::string{"/ws/"}+name()); + handler=std::make_shared(); + sc_comm_singleton::inst().registerWebSocketHandler((std::string{"/ws/"}+name()).c_str(), handler); + } +} + void uart::clock_cb() { this->clk = clk_i.read(); } @@ -74,11 +100,12 @@ void uart::transmit_data() { std::string msg(queue.begin(), queue.end()-1); LOG(INFO) << this->name() << " transmit: '" << msg << "'"; sc_core::sc_time now = sc_core::sc_time_stamp(); - sc_comm_singleton::inst().execute([this, msg, now](){ - std::stringstream os; - os << "{\"time\":\"" << now << "\",\"message\":\""<handler->send(os.str()); - }); + if(handler) + sc_comm_singleton::inst().execute([this, msg, now](){ + std::stringstream os; + os << "{\"time\":\"" << now << "\",\"message\":\""<handler->send(os.str()); + }); queue.clear(); } } diff --git a/riscv/gen_input/RV32C.core_desc b/riscv/gen_input/RV32C.core_desc index 6b453b8..77ca0af 100644 --- a/riscv/gen_input/RV32C.core_desc +++ b/riscv/gen_input/RV32C.core_desc @@ -12,6 +12,13 @@ InsructionSet RV32CI { PC[XLEN](is_pc) } instructions{ + JALR(no_cont){ // overwriting the implementation if rv32i, alignment does not need to be word + encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b1100111; + args_disass: "x%rd$d, x%rs1$d, 0x%imm$x"; + if(rd!=0) X[rd] <= PC+4; + val ret[XLEN] <= X[rs1]+ imm; + PC<=ret& ~0x1; + } C.ADDI4SPN { //(RES, imm=0) encoding: b000 | imm[5:4] | imm[9:6] | imm[2:2] | imm[3:3] | rd[2:0] | b00; args_disass: "x%rd$d, 0x%imm$05x"; diff --git a/riscv/gen_input/RV32IBase.core_desc b/riscv/gen_input/RV32IBase.core_desc index 9b0d16b..70cd43b 100644 --- a/riscv/gen_input/RV32IBase.core_desc +++ b/riscv/gen_input/RV32IBase.core_desc @@ -38,9 +38,14 @@ InsructionSet RV32IBase { JALR(no_cont){ encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b1100111; args_disass: "x%rd$d, x%rs1$d, 0x%imm$x"; - if(rd!=0) X[rd] <= PC+4; - val ret[XLEN] <= X[rs1]+ imm; - PC<=ret& ~0x1; + val new_pc[XLEN] <= X[rs1]+ imm; + val align[XLEN] <= new_pc & 0x2; + if(align != 0){ + raise(0, 0) + } else { + if(rd!=0) X[rd] <= PC+4; + PC<=new_pc & ~0x1; + } } BEQ(no_cont){ encoding: imm[12:12]s |imm[10:5]s | rs2[4:0] | rs1[4:0] | b000 | imm[4:1]s | imm[11:11]s | b1100011; @@ -154,17 +159,29 @@ InsructionSet RV32IBase { SLLI { encoding: b0000000 | shamt[4:0] | rs1[4:0] | b001 | rd[4:0] | b0010011; args_disass:"x%rd$d, x%rs1$d, %shamt%"; - if(rd != 0) X[rd] <= shll(X[rs1], shamt); + if(shamt > 31){ + raise(0,0) + } else { + if(rd != 0) X[rd] <= shll(X[rs1], shamt); + } } SRLI { encoding: b0000000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0010011; args_disass:"x%rd$d, x%rs1$d, %shamt%"; - if(rd != 0) X[rd] <= shrl(X[rs1], shamt); + if(shamt > 31){ + raise(0,0) + } else { + if(rd != 0) X[rd] <= shrl(X[rs1], shamt); + } } SRAI { encoding: b0100000 | shamt[4:0] | rs1[4:0] | b101 | rd[4:0] | b0010011; args_disass:"x%rd$d, x%rs1$d, %shamt%"; - if(rd != 0) X[rd] <= shra(X[rs1], shamt); + if(shamt > 31){ + raise(0,0) + } else { + if(rd != 0) X[rd] <= shra(X[rs1], shamt); + } } ADD { encoding: b0000000 | rs2[4:0] | rs1[4:0] | b000 | rd[4:0] | b0110011; diff --git a/riscv/gen_input/RV64A.core_desc b/riscv/gen_input/RV64A.core_desc index f7875d9..91ffb3d 100644 --- a/riscv/gen_input/RV64A.core_desc +++ b/riscv/gen_input/RV64A.core_desc @@ -1,6 +1,7 @@ import "RV64IBase.core_desc" +import "RV32A.core_desc" -InsructionSet RV64A extends RV64IBase{ +InsructionSet RV64A extends RV64IBase { address_spaces { RES[8] diff --git a/riscv/gen_input/RV64IBase.core_desc b/riscv/gen_input/RV64IBase.core_desc index 68ca175..013b716 100644 --- a/riscv/gen_input/RV64IBase.core_desc +++ b/riscv/gen_input/RV64IBase.core_desc @@ -39,7 +39,7 @@ InsructionSet RV64IBase extends RV32IBase { encoding: imm[11:0]s | rs1[4:0] | b000 | rd[4:0] | b0011011; args_disass:"x%rd$d, x%rs1$d, %imm%"; if(rd != 0){ - val res[32] <= X[rs1]{32} + imm{32}; + val res[32] <= X[rs1]{32} + imm; X[rd] <= sext(res); } } diff --git a/riscv/gen_input/minres_rv.core_desc b/riscv/gen_input/minres_rv.core_desc index a34c6f5..d6e74fc 100644 --- a/riscv/gen_input/minres_rv.core_desc +++ b/riscv/gen_input/minres_rv.core_desc @@ -6,7 +6,7 @@ import "RV64IBase.core_desc" //import "RV64M.core_desc" import "RV64A.core_desc" -Core RV32IMAC provides RV32IBase,RV32M,RV32A, RV32CI { +Core RV32IMAC provides RV32IBase, RV32M, RV32A, RV32CI { template:"vm_riscv.in.cpp"; constants { XLEN:=32; @@ -25,8 +25,8 @@ Core RV32IMAC provides RV32IBase,RV32M,RV32A, RV32CI { } -Core RV64IA provides RV64IBase,RV64A { - template:"vm_riscv.in.cpp"; +Core RV64IA provides RV64IBase, RV64A, RV32A { + template:"vm_riscv.in.cpp"; constants { XLEN:=64; XLEN2:=128; @@ -37,7 +37,7 @@ Core RV64IA provides RV64IBase,RV64A { fencevmal:=2; fencevmau:=3; // XL ZYXWVUTSRQPONMLKJIHGFEDCBA - MISA_VAL:=0b10000000000001000001000100000000; + MISA_VAL:=0b10000000000001000000000100000001; PGSIZE := 4096; //1 << 12; PGMASK := 4095; //PGSIZE-1 } diff --git a/riscv/incl/iss/arch/riscv_hart_msu_vp.h b/riscv/incl/iss/arch/riscv_hart_msu_vp.h index 15a7ecb..06c7f8b 100644 --- a/riscv/incl/iss/arch/riscv_hart_msu_vp.h +++ b/riscv/incl/iss/arch/riscv_hart_msu_vp.h @@ -29,7 +29,7 @@ * POSSIBILITY OF SUCH DAMAGE. * * Contributors: - * eyck@minres.com - initial API and implementation + * eyck@minres.com - initial implementation ******************************************************************************/ #ifndef _RISCV_CORE_H_ @@ -970,12 +970,13 @@ iss::status riscv_hart_msu_vp::write_mem(phys_addr_t paddr, unsigned lengt if (tohost_upper || (tohost_lower && to_host_wr_cnt > 0)) { switch (hostvar >> 48) { case 0: - if (hostvar != 0x1) + if (hostvar != 0x1){ LOG(FATAL) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar << "), stopping simulation"; - else + }else{ LOG(INFO) << "tohost value is 0x" << std::hex << hostvar << std::dec << " (" << hostvar << "), stopping simulation"; + } throw(iss::simulation_stopped(hostvar)); case 0x0101: { char c = static_cast(hostvar & 0xff); diff --git a/riscv/incl/iss/arch/rv32imac.h b/riscv/incl/iss/arch/rv32imac.h index 5dc4bf4..78ea62f 100644 --- a/riscv/incl/iss/arch/rv32imac.h +++ b/riscv/incl/iss/arch/rv32imac.h @@ -28,7 +28,7 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // -// Created on: Fri Nov 17 20:34:49 CET 2017 +// Created on: Sun Nov 19 14:05:47 CET 2017 // * rv32imac.h Author: // //////////////////////////////////////////////////////////////////////////////// diff --git a/riscv/incl/iss/arch/rv64ia.h b/riscv/incl/iss/arch/rv64ia.h index 2bfbd96..b0b2d09 100644 --- a/riscv/incl/iss/arch/rv64ia.h +++ b/riscv/incl/iss/arch/rv64ia.h @@ -28,7 +28,7 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // -// Created on: Fri Nov 17 20:34:49 CET 2017 +// Created on: Sun Nov 19 14:05:47 CET 2017 // * rv64ia.h Author: // //////////////////////////////////////////////////////////////////////////////// @@ -48,7 +48,7 @@ struct rv64ia; template<> struct traits { - enum constants {XLEN=64,XLEN2=128,XLEN_BIT_MASK=63,PCLEN=64,fence=0,fencei=1,fencevmal=2,fencevmau=3,MISA_VAL=2147750144,PGSIZE=4096,PGMASK=4095}; + enum constants {XLEN=64,XLEN2=128,XLEN_BIT_MASK=63,PCLEN=64,fence=0,fencei=1,fencevmal=2,fencevmau=3,MISA_VAL=2147746049,PGSIZE=4096,PGMASK=4095}; enum reg_e { X0, diff --git a/riscv/src/internal/vm_riscv.in.cpp b/riscv/src/internal/vm_riscv.in.cpp index 2d37da0..c87e818 100644 --- a/riscv/src/internal/vm_riscv.in.cpp +++ b/riscv/src/internal/vm_riscv.in.cpp @@ -222,16 +222,24 @@ private: ****************************************************************************/ std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, llvm::BasicBlock *bb) { - // this->gen_sync(iss::PRE_SYNC); - this->builder->CreateStore(this->builder->CreateLoad(get_reg_ptr(traits::NEXT_PC), true), - get_reg_ptr(traits::PC), true); - this->builder->CreateStore( - this->builder->CreateAdd(this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), true), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), true); - if (this->debugging_enabled()) this->gen_sync(iss::PRE_SYNC); + bb->setName("illegal_instruction"); + + this->gen_sync(iss::PRE_SYNC); + if(this->disass_enabled){ + /* generate console output when executing the command */ + /* generate console output when executing the command */ + boost::format ins_fmter("DB x%1$d"); + ins_fmter % (uint64_t)instr; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder->CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + } pc = pc + ((instr & 3) == 3 ? 4 : 2); - this->gen_raise_trap(0, 2); // illegal instruction trap + + this->gen_raise_trap(0, 2); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ this->gen_trap_check(this->leave_blk); return std::make_tuple(iss::vm::BRANCH, nullptr); diff --git a/riscv/src/internal/vm_rv64ia.cpp b/riscv/src/internal/vm_rv64ia.cpp index fbd5aa8..a609ff7 100644 --- a/riscv/src/internal/vm_rv64ia.cpp +++ b/riscv/src/internal/vm_rv64ia.cpp @@ -215,7 +215,7 @@ private: }; /* start generated code */ - const InstructionDesriptor instr_descr[75] = { + const InstructionDesriptor instr_descr[86] = { /* entries are: valid value, valid mask, function ptr */ /* instruction LWU */ {32, 0b00000000000000000110000000000011, 0b00000000000000000111000001111111, &this_class::__lwu}, @@ -223,12 +223,6 @@ private: {32, 0b00000000000000000011000000000011, 0b00000000000000000111000001111111, &this_class::__ld}, /* instruction SD */ {32, 0b00000000000000000011000000100011, 0b00000000000000000111000001111111, &this_class::__sd}, - /* instruction SLLI */ - {32, 0b00000000000000000001000000010011, 0b11111100000000000111000001111111, &this_class::__slli}, - /* instruction SRLI */ - {32, 0b00000000000000000101000000010011, 0b11111100000000000111000001111111, &this_class::__srli}, - /* instruction SRAI */ - {32, 0b01000000000000000101000000010011, 0b11111100000000000111000001111111, &this_class::__srai}, /* instruction ADDIW */ {32, 0b00000000000000000000000000011011, 0b00000000000000000111000001111111, &this_class::__addiw}, /* instruction SLLIW */ @@ -295,6 +289,12 @@ private: {32, 0b00000000000000000110000000010011, 0b00000000000000000111000001111111, &this_class::__ori}, /* instruction ANDI */ {32, 0b00000000000000000111000000010011, 0b00000000000000000111000001111111, &this_class::__andi}, + /* instruction SLLI */ + {32, 0b00000000000000000001000000010011, 0b11111110000000000111000001111111, &this_class::__slli}, + /* instruction SRLI */ + {32, 0b00000000000000000101000000010011, 0b11111110000000000111000001111111, &this_class::__srli}, + /* instruction SRAI */ + {32, 0b01000000000000000101000000010011, 0b11111110000000000111000001111111, &this_class::__srai}, /* instruction ADD */ {32, 0b00000000000000000000000000110011, 0b11111110000000000111000001111111, &this_class::__add}, /* instruction SUB */ @@ -367,6 +367,28 @@ private: {32, 0b11000000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amominu_d}, /* instruction AMOMAXU.D */ {32, 0b11100000000000000011000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_d}, + /* instruction LR.W */ + {32, 0b00010000000000000010000000101111, 0b11111001111100000111000001111111, &this_class::__lr_w}, + /* instruction SC.W */ + {32, 0b00011000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__sc_w}, + /* instruction AMOSWAP.W */ + {32, 0b00001000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoswap_w}, + /* instruction AMOADD.W */ + {32, 0b00000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoadd_w}, + /* instruction AMOXOR.W */ + {32, 0b00100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoxor_w}, + /* instruction AMOAND.W */ + {32, 0b01100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoand_w}, + /* instruction AMOOR.W */ + {32, 0b01000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amoor_w}, + /* instruction AMOMIN.W */ + {32, 0b10000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomin_w}, + /* instruction AMOMAX.W */ + {32, 0b10100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomax_w}, + /* instruction AMOMINU.W */ + {32, 0b11000000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amominu_w}, + /* instruction AMOMAXU.W */ + {32, 0b11100000000000000010000000101111, 0b11111000000000000111000001111111, &this_class::__amomaxu_w}, }; // instruction LWU std::tuple __lwu(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ @@ -483,111 +505,6 @@ private: return std::make_tuple(vm::CONT, bb); } - // instruction SLLI - std::tuple __slli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SLLI"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - uint8_t fld_shamt_val = 0 | (bit_sub<20,6>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("SLLI x%1$d, x%2$d, %3%"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_shamt_val; - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), - }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); - } - pc=pc+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateShl( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(64U, fld_shamt_val)); - this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction SRLI - std::tuple __srli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRLI"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - uint8_t fld_shamt_val = 0 | (bit_sub<20,6>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("SRLI x%1$d, x%2$d, %3%"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_shamt_val; - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), - }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); - } - pc=pc+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateLShr( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(64U, fld_shamt_val)); - this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - - // instruction SRAI - std::tuple __srai(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ - bb->setName("SRAI"); - - this->gen_sync(iss::PRE_SYNC); - - uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); - uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); - uint8_t fld_shamt_val = 0 | (bit_sub<20,6>(instr)); - if(this->disass_enabled){ - /* generate console output when executing the command */ - boost::format ins_fmter("SRAI x%1$d, x%2$d, %3%"); - ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_shamt_val; - std::vector args { - this->core_ptr, - this->gen_const(64, pc.val), - this->builder->CreateGlobalStringPtr(ins_fmter.str()), - }; - this->builder->CreateCall(this->mod->getFunction("print_disass"), args); - } - pc=pc+4; - - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAShr( - this->gen_reg_load(fld_rs1_val, 0), - this->gen_const(64U, fld_shamt_val)); - this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); - } - this->gen_set_pc(pc, traits::NEXT_PC); - this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ - bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ - this->gen_trap_check(bb); - return std::make_tuple(vm::CONT, bb); - } - // instruction ADDIW std::tuple __addiw(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("ADDIW"); @@ -1113,19 +1030,43 @@ private: } pc=pc+4; - if(fld_rd_val != 0){ - Value* X_rd_val = this->builder->CreateAdd( - this->gen_reg_load(traits::PC, 0), - this->gen_const(64U, 4)); - this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); - } - Value* ret_val = this->builder->CreateAdd( + Value* new_pc_val = this->builder->CreateAdd( this->gen_reg_load(fld_rs1_val, 0), this->gen_const(64U, fld_imm_val)); - Value* PC_val = this->builder->CreateAnd( - ret_val, - this->builder->CreateNot(this->gen_const(64U, 1))); - this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + Value* align_val = this->builder->CreateAnd( + new_pc_val, + this->gen_const(64U, 2)); + llvm::BasicBlock* bbnext = llvm::BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + llvm::BasicBlock* bb_then = llvm::BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + llvm::BasicBlock* bb_else = llvm::BasicBlock::Create(this->mod->getContext(), "elsebr", this->func, bbnext); + // this->builder->SetInsertPoint(bb); + this->gen_cond_branch(this->builder->CreateICmp( + ICmpInst::ICMP_NE, + align_val, + this->gen_const(64U, 0)), + bb_then, + bb_else); + this->builder->SetInsertPoint(bb_then); + { + this->gen_raise_trap(0, 0); + } + this->builder->CreateBr(bbnext); + this->builder->SetInsertPoint(bb_else); + { + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder->CreateAdd( + this->gen_reg_load(traits::PC, 1), + this->gen_const(64U, 4)); + this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + Value* PC_val = this->builder->CreateAnd( + new_pc_val, + this->builder->CreateNot(this->gen_const(64U, 1))); + this->builder->CreateStore(PC_val, get_reg_ptr(traits::NEXT_PC), false); + } + this->builder->CreateBr(bbnext); + bb=bbnext; + this->builder->SetInsertPoint(bb); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ this->gen_trap_check(this->leave_blk); return std::make_tuple(iss::vm::BRANCH, nullptr); @@ -1914,6 +1855,111 @@ private: return std::make_tuple(vm::CONT, bb); } + // instruction SLLI + std::tuple __slli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("SLLI"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_shamt_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("SLLI x%1$d, x%2$d, %3%"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_shamt_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder->CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + } + pc=pc+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder->CreateShl( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(64U, fld_shamt_val)); + this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction SRLI + std::tuple __srli(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("SRLI"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_shamt_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("SRLI x%1$d, x%2$d, %3%"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_shamt_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder->CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + } + pc=pc+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder->CreateLShr( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(64U, fld_shamt_val)); + this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction SRAI + std::tuple __srai(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("SRAI"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_shamt_val = 0 | (bit_sub<20,5>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("SRAI x%1$d, x%2$d, %3%"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_shamt_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder->CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + } + pc=pc+4; + + if(fld_rd_val != 0){ + Value* X_rd_val = this->builder->CreateAShr( + this->gen_reg_load(fld_rs1_val, 0), + this->gen_const(64U, fld_shamt_val)); + this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + // instruction ADD std::tuple __add(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ bb->setName("ADD"); @@ -3374,22 +3420,600 @@ private: return std::make_tuple(vm::CONT, bb); } + // instruction LR.W + std::tuple __lr_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("LR.W"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("LR.W x%1$d, x%2$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder->CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + } + pc=pc+4; + + if(fld_rd_val != 0){ + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* X_rd_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + Value* RES_offs_val = this->gen_ext( + this->builder->CreateNeg(this->gen_const(8U, 1)), + 32, + true); + this->gen_write_mem( + traits::RES, + offs_val, + this->builder->CreateZExtOrTrunc(RES_offs_val,this->get_type(32))); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction SC.W + std::tuple __sc_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("SC.W"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("SC.W x%1$d, x%2$d, x%3$d"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder->CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + } + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_read_mem(traits::RES, offs_val, 32/8); + llvm::BasicBlock* bbnext = llvm::BasicBlock::Create(this->mod->getContext(), "endif", this->func, this->leave_blk); + llvm::BasicBlock* bb_then = llvm::BasicBlock::Create(this->mod->getContext(), "thenbr", this->func, bbnext); + // this->builder->SetInsertPoint(bb); + this->gen_cond_branch(this->builder->CreateICmp( + ICmpInst::ICMP_NE, + res1_val, + this->gen_const(32U, 0)), + bb_then, + bbnext); + this->builder->SetInsertPoint(bb_then); + { + Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 1); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + } + this->builder->CreateBr(bbnext); + bb=bbnext; + this->builder->SetInsertPoint(bb); + if(fld_rd_val != 0){ + Value* X_rd_val = this->gen_choose( + this->builder->CreateICmp( + ICmpInst::ICMP_NE, + res1_val, + this->gen_const(64U, 0)), + this->gen_const(64U, 0), + this->gen_const(64U, 1), + 64); + this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction AMOSWAP.W + std::tuple __amoswap_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("AMOSWAP.W"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOSWAP.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder->CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + } + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + if(fld_rd_val != 0){ + Value* X_rd_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + Value* MEM_offs_val = this->gen_reg_load(fld_rs2_val, 0); + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction AMOADD.W + std::tuple __amoadd_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("AMOADD.W"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOADD.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder->CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + } + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(fld_rd_val != 0){ + Value* X_rd_val = res1_val; + this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + Value* res2_val = this->builder->CreateAdd( + res1_val, + this->gen_reg_load(fld_rs2_val, 0)); + Value* MEM_offs_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction AMOXOR.W + std::tuple __amoxor_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("AMOXOR.W"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOXOR.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder->CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + } + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(fld_rd_val != 0){ + Value* X_rd_val = res1_val; + this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + Value* res2_val = this->builder->CreateXor( + res1_val, + this->gen_reg_load(fld_rs2_val, 0)); + Value* MEM_offs_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction AMOAND.W + std::tuple __amoand_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("AMOAND.W"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOAND.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder->CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + } + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(fld_rd_val != 0){ + Value* X_rd_val = res1_val; + this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + Value* res2_val = this->builder->CreateAnd( + res1_val, + this->gen_reg_load(fld_rs2_val, 0)); + Value* MEM_offs_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction AMOOR.W + std::tuple __amoor_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("AMOOR.W"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOOR.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder->CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + } + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(fld_rd_val != 0){ + Value* X_rd_val = res1_val; + this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + Value* res2_val = this->builder->CreateOr( + res1_val, + this->gen_reg_load(fld_rs2_val, 0)); + Value* MEM_offs_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction AMOMIN.W + std::tuple __amomin_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("AMOMIN.W"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOMIN.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder->CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + } + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(fld_rd_val != 0){ + Value* X_rd_val = res1_val; + this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + Value* res2_val = this->gen_choose( + this->builder->CreateICmp( + ICmpInst::ICMP_SGT, + this->gen_ext( + res1_val, + 64, true), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 64, true)), + this->gen_reg_load(fld_rs2_val, 0), + res1_val, + 64); + Value* MEM_offs_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction AMOMAX.W + std::tuple __amomax_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("AMOMAX.W"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOMAX.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder->CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + } + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + true); + if(fld_rd_val != 0){ + Value* X_rd_val = res1_val; + this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + Value* res2_val = this->gen_choose( + this->builder->CreateICmp( + ICmpInst::ICMP_SLT, + this->gen_ext( + res1_val, + 64, true), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 64, true)), + this->gen_reg_load(fld_rs2_val, 0), + res1_val, + 64); + Value* MEM_offs_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction AMOMINU.W + std::tuple __amominu_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("AMOMINU.W"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOMINU.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder->CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + } + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + false); + if(fld_rd_val != 0){ + Value* X_rd_val = res1_val; + this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + Value* res2_val = this->gen_choose( + this->builder->CreateICmp( + ICmpInst::ICMP_UGT, + res1_val, + this->gen_reg_load(fld_rs2_val, 0)), + this->gen_reg_load(fld_rs2_val, 0), + res1_val, + 64); + Value* MEM_offs_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + + // instruction AMOMAXU.W + std::tuple __amomaxu_w(virt_addr_t& pc, code_word_t instr, llvm::BasicBlock* bb){ + bb->setName("AMOMAXU.W"); + + this->gen_sync(iss::PRE_SYNC); + + uint8_t fld_rd_val = 0 | (bit_sub<7,5>(instr)); + uint8_t fld_rs1_val = 0 | (bit_sub<15,5>(instr)); + uint8_t fld_rs2_val = 0 | (bit_sub<20,5>(instr)); + uint8_t fld_rl_val = 0 | (bit_sub<25,1>(instr)); + uint8_t fld_aq_val = 0 | (bit_sub<26,1>(instr)); + if(this->disass_enabled){ + /* generate console output when executing the command */ + boost::format ins_fmter("AMOMAXU.W x%1$d, x%2$d, x%3$d (aqu=%4$d,rel=%5$d)"); + ins_fmter % (uint64_t)fld_rd_val % (uint64_t)fld_rs1_val % (uint64_t)fld_rs2_val % (uint64_t)fld_aq_val % (uint64_t)fld_rl_val; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder->CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + } + pc=pc+4; + + Value* offs_val = this->gen_reg_load(fld_rs1_val, 0); + Value* res1_val = this->gen_ext( + this->gen_read_mem(traits::MEM, offs_val, 32/8), + 64, + false); + if(fld_rd_val != 0){ + Value* X_rd_val = res1_val; + this->builder->CreateStore(X_rd_val, get_reg_ptr(fld_rd_val), false); + } + Value* res2_val = this->gen_choose( + this->builder->CreateICmp( + ICmpInst::ICMP_ULT, + this->gen_ext( + res1_val, + 64, false), + this->gen_ext( + this->gen_reg_load(fld_rs2_val, 0), + 64, false)), + this->gen_reg_load(fld_rs2_val, 0), + res1_val, + 64); + Value* MEM_offs_val = res2_val; + this->gen_write_mem( + traits::MEM, + offs_val, + this->builder->CreateZExtOrTrunc(MEM_offs_val,this->get_type(32))); + this->gen_set_pc(pc, traits::NEXT_PC); + this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ + bb = llvm::BasicBlock::Create(this->mod->getContext(), "entry", this->func, this->leave_blk); /* create next BasicBlock in chain */ + this->gen_trap_check(bb); + return std::make_tuple(vm::CONT, bb); + } + /* end generated code */ /**************************************************************************** * end opcode definitions ****************************************************************************/ std::tuple illegal_intruction(virt_addr_t &pc, code_word_t instr, llvm::BasicBlock *bb) { - // this->gen_sync(iss::PRE_SYNC); - this->builder->CreateStore(this->builder->CreateLoad(get_reg_ptr(traits::NEXT_PC), true), - get_reg_ptr(traits::PC), true); - this->builder->CreateStore( - this->builder->CreateAdd(this->builder->CreateLoad(get_reg_ptr(traits::ICOUNT), true), - this->gen_const(64U, 1)), - get_reg_ptr(traits::ICOUNT), true); - if (this->debugging_enabled()) this->gen_sync(iss::PRE_SYNC); + bb->setName("illegal_instruction"); + + this->gen_sync(iss::PRE_SYNC); + if(this->disass_enabled){ + /* generate console output when executing the command */ + /* generate console output when executing the command */ + boost::format ins_fmter("DB 0x%1$x"); + ins_fmter % (uint64_t)instr; + std::vector args { + this->core_ptr, + this->gen_const(64, pc.val), + this->builder->CreateGlobalStringPtr(ins_fmter.str()), + }; + this->builder->CreateCall(this->mod->getFunction("print_disass"), args); + } pc = pc + ((instr & 3) == 3 ? 4 : 2); - this->gen_raise_trap(0, 2); // illegal instruction trap + + this->gen_raise_trap(0, 2); this->gen_sync(iss::POST_SYNC); /* call post-sync if needed */ this->gen_trap_check(this->leave_blk); return std::make_tuple(iss::vm::BRANCH, nullptr); diff --git a/riscv/src/main.cpp b/riscv/src/main.cpp index c21cc03..05331da 100644 --- a/riscv/src/main.cpp +++ b/riscv/src/main.cpp @@ -29,7 +29,7 @@ // POSSIBILITY OF SUCH DAMAGE. // // Contributors: -// eyck@minres.com - initial API and implementation +// eyck@minres.com - initial implementation //////////////////////////////////////////////////////////////////////////////// #include @@ -54,23 +54,24 @@ int main(int argc, char *argv[]) { // clang-format off desc.add_options() ("help,h", "Print help message") - ("verbose,v", po::value()->implicit_value(0), "Sets logging verbosity") - ("log-file", po::value(), "Sets default log file.") + ("loglevel,l", po::value()->implicit_value(2), "Sets logging verbosity") + ("logfile,f", po::value(), "Sets default log file.") ("disass,d", po::value()->implicit_value(""), "Enables disassembly") - ("elf,l", po::value>(), "ELF file(s) to load") + ("elf", po::value>(), "ELF file(s) to load") ("gdb-port,g", po::value()->default_value(0), "enable gdb server and specify port to use") ("input,i", po::value(), "the elf file to load (instead of hex files)") ("dump-ir", "dump the intermediate representation") ("cycles,c", po::value()->default_value(-1), "number of cycles to run") ("systemc,s", "Run as SystemC simulation") - ("time", po::value(), "SystemC siimulation time in ms") + ("time", po::value(), "SystemC simulation time in ms") ("reset,r", po::value(), "reset address") ("trace", po::value(), "enable tracing, or cmbintation of 1=signals and 2=TX text, 4=TX compressed text, 6=TX in SQLite") ("mem,m", po::value(), "the memory input file") - ("rv64", "run RV64"); + ("isa", po::value()->default_value("rv32imac"), "isa to use for simulation"); // clang-format on + auto parsed = po::command_line_parser(argc, argv).options(desc).allow_unregistered().run(); try { - po::store(po::parse_command_line(argc, argv, desc), clim); // can throw + po::store(parsed, clim); // can throw // --help option if (clim.count("help")) { std::cout << "DBT-RISE-RiscV simulator for RISC-V" << std::endl << desc << std::endl; @@ -83,14 +84,16 @@ int main(int argc, char *argv[]) { std::cerr << desc << std::endl; return 1; } - if (clim.count("verbose")) { - auto l = logging::as_log_level(clim["verbose"].as()); + std::vector args = collect_unrecognized(parsed.options, po::include_positional); + + if (clim.count("loglevel")) { + auto l = logging::as_log_level(clim["loglevel"].as()); LOGGER(DEFAULT)::reporting_level() = l; LOGGER(connection)::reporting_level() = l; } - if (clim.count("log-file")) { + if (clim.count("logfile")) { // configure the connection logger - auto f = fopen(clim["log-file"].as().c_str(), "w"); + auto f = fopen(clim["logfile"].as().c_str(), "w"); LOG_OUTPUT(DEFAULT)::stream() = f; LOG_OUTPUT(connection)::stream() = f; } @@ -101,19 +104,21 @@ int main(int argc, char *argv[]) { bool dump = clim.count("dump-ir"); // instantiate the simulator std::unique_ptr vm{nullptr}; - if (clim.count("rv64") == 1) { - auto cpu = new iss::arch::riscv_hart_msu_vp(); - vm = iss::create(cpu, clim["gdb-port"].as(), dump); + if (clim["isa"].as().substr(0, 4)=="rv64") { + iss::arch::rv64ia* cpu = new iss::arch::riscv_hart_msu_vp(); + vm = iss::create(cpu, clim["gdb-port"].as(), dump); + } else if (clim["isa"].as().substr(0, 4)=="rv32") { + iss::arch::rv32imac* cpu = new iss::arch::riscv_hart_msu_vp(); + vm = iss::create(cpu, clim["gdb-port"].as(), dump); } else { - auto cpu = new iss::arch::riscv_hart_msu_vp(); - vm = iss::create(cpu, clim["gdb-port"].as(), dump); + LOG(ERROR) << "Illegal argument value for '--isa': " << clim["isa"].as() << std::endl; + return 127; } - if (clim.count("elf")) { + if (clim.count("elf")) for (std::string input : clim["elf"].as>()) vm->get_arch()->load_file(input); - } else if (clim.count("mem")) { + if (clim.count("mem")) vm->get_arch()->load_file(clim["mem"].as(), iss::arch::traits::MEM); - } - + for (std::string input : args) vm->get_arch()->load_file(input);// treat remaining arguments as elf files if (clim.count("disass")) { vm->setDisassEnabled(true); LOGGER(disass)::reporting_level() = logging::INFO; diff --git a/sc-components b/sc-components index 174e0f5..02cb175 160000 --- a/sc-components +++ b/sc-components @@ -1 +1 @@ -Subproject commit 174e0f55f11fa932c88b99e352e5e9b58cb9ce71 +Subproject commit 02cb1756166adb7074f6e5dfa106ca5ab04176c6 diff --git a/simple-system.json b/simple-system.json new file mode 100644 index 0000000..a2bd7ac --- /dev/null +++ b/simple-system.json @@ -0,0 +1,13 @@ +{ + "i_simple_system":{ + "i_uart0":{ + "write_to_ws": false + }, + "i_uart1":{ + "write_to_ws": false + }, + "i_gpio0":{ + "write_to_ws": false + } + } +}