WepSIM: Web Elemental Processor Simulator
Table of contents
- Getting WepSIM
- Run WepSIM
- Install WepSIM
- Getting Started
- Visual UI
- Command Line
- Getting Started: Developers
- WepSIM Source Code
- WepSIM engine API
- WepSIM control API
- WepSIM on Google Colab
- WepSIM for Apache Cordova
Getting WepSIM
1) Run WepSIM
-
From Web, please:
- Check you have a compatible Web browser:
- Google Chrome 90+, Mozilla Firefox 90+, Microsoft Edge 90+, and Apple Safari 15+
- Open your (compatible) Web browser
- Click on the link https://wepsim.github.io/wepsim
- A nightly build version is also available at https://acaldero.github.io/wepsim
- Check you have a compatible Web browser:
-
From Linux/Unix command line, please:
- Check you have installed Node v10.5.0+, and Bash 4.4.19+:
- sudo apt-get install nodejs npm bash -y
- Get WepSIM by executing:
- wget https://github.com/acaldero/wepsim/releases/download/v2.2.0/wepsim-2.2.0.zip
- unzip wepsim-2.2.0.zip
- cd wepsim-2.2.0
- npm install terser jq jshint yargs clear inquirer fuzzy inquirer-command-prompt inquirer-autocomplete-prompt
- Execute wepsim.sh with the help flag in order to show the available command switches:
- ./wepsim.sh -h
- Check you have installed Node v10.5.0+, and Bash 4.4.19+:
- WepSIM can be installed on Android 9.0+ from the Goole Play Store at https://play.google.com/store/apps/details?id=es.uc3m.inf.arcos.wepsim
- For other platforms, please follow those steps in order to install WepSIM as a Progressive Web Application (PWA):
| Step | iOS | Android | Action to perform |
|---|---|---|---|
| 1 | First, open Safari (iOS, MacOS) or Chrome (Android, Windows, Linux) and load https://acaldero.github.io/wepsim. From the top-right corner, tap on the share icon (Safari) or the menu icon (Chrome). |
||
| 2 | Move within share options until 'add to home screen' option and click on it. | ||
| 3 | Finally, click in the 'add' option. | ||
| 4 | Then, WepSIM can be launched from the home screen icon. |
A) Steps to execute a WepSIM example
- First, we need to load WepSIM in your favorite web browser. Then click on the Examples button to open the Examples dialog:
- In the Examples dialog, please click on the colored 'title' of the example and WepSIM will load and compile the associated microcode and assembly code:
- In the simulator workspace you can execute step by step and analyze the state of the components. It is possible to work both, at assembly level or at microcode level:
B) Typical workflow to modify an existing example or build your own experiment
- First, we need to load WepSIM in your web browser. Then you should go to the microcode editor workspace:
- You can load an existing microcode or edit a new one. You have to microcompile the microcode to load the binary into the CPU's control memory:
- Next, you could go to the assembly editor workspace. In the editor workspace you can load an existing assembly code or edit a new one:
- The instructions set defined in the previous microcode is used to create your assembly code. You have to compile the assembly code to load the binary into the main memory:
- Finally, go back to the simulator workspace, and you can execute step by step and analyze the state of the components. It is possible to work at assembly level or at microcode level:
C) Step to change the WepSIM configuration
- From the general toolbar, the configuration button allows users to personalize several options:
- From the general toolbar, please use the left-upper slider to change the CPU/CU size:
D) Typical steps to use the "State Management" in WepSIM
- The value of every visible hardware element is the state in a clock cycle. WepSIM has also a 'state management' dialog where users can see the current state, and check the differences between the two states.
- From the execution toolbar, please click over the 'state' button to show the state manager dialog:
A) Run (and print the final state)
- From the command line it is possible to 'run' the 'asm-mips_s1e1.txt' assembly for the 'ep' architecture with the 'mc-ep_mips_base.txt' microcode, and print the final state:
./wepsim.sh -a run -m ep -f ./examples/microcode/mc-ep_mips_base.txt -s ./examples/assembly/asm-mips_s1e1.txt
register R2 = 0x2; register R3 = 0x1; register R5 = 0x1; register R29 = 0xfffff; register PC = 0x8018; memory 0x8000 = 0x8400002; memory 0x8004 = 0x8600001; memory 0x8008 = 0xa21809; memory 0x800c = 0x8400002; memory 0x8010 = 0x8600001; memory 0x8014 = 0xa2180a;
register R2 = 0x2; register R3 = 0x1; register R5 = 0x1; register R29 = 0xfffff; register PC = 0x8018; memory 0x8000 = 0x8400002; memory 0x8004 = 0x8600001; memory 0x8008 = 0xa21809; memory 0x800c = 0x8400002; memory 0x8010 = 0x8600001; memory 0x8014 = 0xa2180a;
B) Run step by step
- It is also possible to 'run' 'step by step' the 'asm-ep-s1_e1.txt' assembly for the 'ep' architecture with the 'mc-ep_mips_base.txt' microcode, and print for each assembly instruction the state elements that modify its value:
./wepsim.sh -a stepbystep -m ep -f ./examples/microcode/mc-ep_mips_base.txt -s ./examples/assembly/asm-mips_s1e1.txt
pc, instruction, changes_from_zero_or_current_value
pc = 0x8000, li $2 2, register R2 = 0x2; register R29 = 0xfffff; register PC = 0x8004
pc = 0x8004, li $3 1, register R3 = 0x1; register PC = 0x8008
pc = 0x8008, add $5 $2 $3, register R5 = 0x3; register PC = 0x800c
pc = 0x800c, li $2 2, register PC = 0x8010
pc = 0x8010, li $3 1, register PC = 0x8014
pc = 0x8014, sub $5 $2 $3, register R5 = 0x1; register PC = 0x8018
pc, instruction, changes_from_zero_or_current_value
pc = 0x8000, li $2 2, register R2 = 0x2; register R29 = 0xfffff; register PC = 0x8004
pc = 0x8004, li $3 1, register R3 = 0x1; register PC = 0x8008
pc = 0x8008, add $5 $2 $3, register R5 = 0x3; register PC = 0x800c
pc = 0x800c, li $2 2, register PC = 0x8010
pc = 0x8010, li $3 1, register PC = 0x8014
pc = 0x8014, sub $5 $2 $3, register R5 = 0x1; register PC = 0x8018
C) Run microstep by microstep
- And to 'run' 'microstep by microstep' the 'asm-mips_s1e1.txt' assembly for the 'ep' architecture with the 'mc-ep_mips_base.txt' microcode, and print for each microinstruction the state elements that modify its value:
./wepsim.sh -a microstepbymicrostep -m ep -f ./examples/microcode/mc-ep_mips_base.txt -s ./examples/assembly/asm-mips_s1e1.txt
micropc, microcode, changes_from_zero_or_current_value
micropc = 0x0, T2 C0,
micropc = 0x1, TA R BW=11 M1 C1,
micropc = 0x2, M2 C2 T1 C3, register PC = 0x8004
micropc = 0x3, A0 B=0 C=0,
micropc = 0x67, SE OFFSET=0 SIZE=10000 T3 LC MR=0 SELC=10101 A0 B C=0,register R2 = 0x2; register R29 = 0xfffff
micropc = 0x0, T2 C0,
micropc = 0x1, TA R BW=11 M1 C1,
micropc = 0x2, M2 C2 T1 C3, register PC = 0x8008
micropc = 0x3, A0 B=0 C=0,
micropc = 0x67, SE OFFSET=0 SIZE=10000 T3 LC MR=0 SELC=10101 A0 B C=0,register R3 = 0x1
micropc = 0x0, T2 C0,
micropc = 0x1, TA R BW=11 M1 C1,
micropc = 0x2, M2 C2 T1 C3, register PC = 0x800c
micropc = 0x3, A0 B=0 C=0,
micropc = 0x35, MC MR=0 SELA=1011 SELB=10000 MA=0 MB=0 SELCOP=1010 T6 SELC=10101 LC SELP=11 M7 C7 A0 B C=0,register R5 = 0x3
micropc, microcode, changes_from_zero_or_current_value
micropc = 0x0, T2 C0,
micropc = 0x1, TA R BW=11 M1 C1,
micropc = 0x2, M2 C2 T1 C3, register PC = 0x8004
micropc = 0x3, A0 B=0 C=0,
micropc = 0x67, SE OFFSET=0 SIZE=10000 T3 LC MR=0 SELC=10101 A0 B C=0,register R2 = 0x2; register R29 = 0xfffff
micropc = 0x0, T2 C0,
micropc = 0x1, TA R BW=11 M1 C1,
micropc = 0x2, M2 C2 T1 C3, register PC = 0x8008
micropc = 0x3, A0 B=0 C=0,
micropc = 0x67, SE OFFSET=0 SIZE=10000 T3 LC MR=0 SELC=10101 A0 B C=0,register R3 = 0x1
micropc = 0x0, T2 C0,
micropc = 0x1, TA R BW=11 M1 C1,
micropc = 0x2, M2 C2 T1 C3, register PC = 0x800c
micropc = 0x3, A0 B=0 C=0,
micropc = 0x35, MC MR=0 SELA=1011 SELB=10000 MA=0 MB=0 SELCOP=1010 T6 SELC=10101 LC SELP=11 M7 C7 A0 B C=0,register R5 = 0x3
D) Run & check end state (example when o.k.)
- You can check if the state at the end of the execution is the same as the one stored on file 'cl-mips_s1e1.txt'. You can 'run' the 'asm-mips_s1e1.txt' assembly for the 'ep' architecture with the 'mc-ep_mips_base.txt' microcode (and if it matches the expected state, then the output is going to be):
./wepsim.sh -a check -m ep -f ./examples/microcode/mc-ep_mips_base.txt -s ./examples/assembly/asm-mips_s1e1.txt -r ./examples/checklist/cl-mips_s1e1.txt
OK: Execution: no error reported
OK: Execution: no error reported
E) Run & check end state (example when k.o.)
- You can check if the state at the end of the execution is the same as the one stored on file 'cl-mips_s1e1.txt'. You can 'run' the 'asm-mips_s1e1.txt' assembly for the 'ep' architecture with the 'mc-ep_mips_base.txt' microcode (and if it fails to match the expected state then the output is going to be):
./wepsim.sh -a check -m ep -f ./examples/microcode/mc-ep_mips_base.txt -s ./examples/assembly/asm-mips_s1e1.txt -r ./examples/checklist/cl-mips_s1e2.txt
ERROR: Execution: different results: cpu[R1]='0' (expected '0xf'), cpu[R2]='0x2' (expected '0xf'), cpu[R3]='0' (expected '0x1'), cpu[R29]='0x100000' (expected '0xfffff'), cpu[PC]='0x8078' (expected '0x8018'), memory[0x1000]='0' (expected '0xa07ff0f'), memory[0x1004]='0' (expected '0x10061'), memory[0x1008]='0' (expected '0x7ffff'), memory[0x100c]='0' (expected '0x61000a'), memory[0x1010]='0' (expected '0xf'), memory[0x1014]='0' (expected '0xffffffff'), memory[0x1018]='0' (expected '0x7'), memory[0x101c]='0' (expected '0x12345678'), memory[0x1020]='0' (expected '0x61'), memory[0x1024]='0' (expected '0x6c6c6568'), memory[0x1028]='0' (expected '0x726f776f'), memory[0x102c]='0' (expected '0x646c'), memory[0x8000]='0x8400002' (expected '0x20201000'), memory[0x8004]='0x8600001' (expected '0x10601010'), memory[0x8008]='0xa21809' (expected '0x820000f'), memory[0x800c]='0x8400002' (expected '0x24201000'), memory[0x8010]='0x8600001' (expected '0x840000f'), memory[0x8014]='0xa2180a' (expected '0x14401010'),
ERROR: Execution: different results: cpu[R1]='0' (expected '0xf'), cpu[R2]='0x2' (expected '0xf'), cpu[R3]='0' (expected '0x1'), cpu[R29]='0x100000' (expected '0xfffff'), cpu[PC]='0x8078' (expected '0x8018'), memory[0x1000]='0' (expected '0xa07ff0f'), memory[0x1004]='0' (expected '0x10061'), memory[0x1008]='0' (expected '0x7ffff'), memory[0x100c]='0' (expected '0x61000a'), memory[0x1010]='0' (expected '0xf'), memory[0x1014]='0' (expected '0xffffffff'), memory[0x1018]='0' (expected '0x7'), memory[0x101c]='0' (expected '0x12345678'), memory[0x1020]='0' (expected '0x61'), memory[0x1024]='0' (expected '0x6c6c6568'), memory[0x1028]='0' (expected '0x726f776f'), memory[0x102c]='0' (expected '0x646c'), memory[0x8000]='0x8400002' (expected '0x20201000'), memory[0x8004]='0x8600001' (expected '0x10601010'), memory[0x8008]='0xa21809' (expected '0x820000f'), memory[0x800c]='0x8400002' (expected '0x24201000'), memory[0x8010]='0x8600001' (expected '0x840000f'), memory[0x8014]='0xa2180a' (expected '0x14401010'),
F) Run microstep by microstep with verbalized output
- And finally, it is possible to execute microstep by microstep but with a more verbose description:
./wepsim.sh -a microstepverbalized -m ep -f ./examples/microcode/mc-ep_mips_base.txt -s ./examples/assembly/asm-mips_s1e1.txt
Micropc at 0x0. Activated signals are: T2 C0. Associated actions are: Copy from Program Counter Register to Internal Bus value 0x8000. Load from Internal Bus to Memory Address Register value 0x8000.
Micropc at 0x1. Activated signals are: TA R BW M1 C1. Associated actions are: Copy from Memory Address Register to Address Bus value 0x8000. Memory output = 0x8400002 (Read a word from 0x8000). Select the full Word. Copy from from Memory to Input of Memory Data Register value 0x8400002. Load from Input of Memory Data Register to Memory Data Register value 0x8400002.
Micropc at 0x2. Activated signals are: M2 C2 T1 C3. Associated actions are: Copy to Input of Program Counter Program Counter Register plus four with result 0x8004. Load from Input of Program Counter to Program Counter Register value 0x8004. Copy from Memory Data Register to Internal Bus value 0x8400002. Load from Internal Bus to Instruction Register value 0x8400002. Decode instruction.
Micropc at 0x3. Activated signals are: A0 B C. Associated actions are: Copy from Input ROM to Input microaddress value 0x67. Copy from Output of MUX C to A1 value 0x0. Copy from Wired Zero to Output of MUX C value 0x0.
Micropc at 0x67. Activated signals are: SE OFFSET SIZE T3 LC MR SELC A0 B C. Associated actions are: Copy from Instruction Register to Input of T3 Tristate value 0x2 (copied 16 bits from bit 0). Copy from Instruction Register to Input of T3 Tristate value 0x2 (copied 16 bits from bit 0). Copy from Instruction Register to Input of T3 Tristate value 0x2 (copied 16 bits from bit 0). Copy from Input of T3 Tristate to Internal Bus value 0x2. Copy to Register 2 the value 0x2. Copy from IR[SelA], from IR[SelB], and from IR[SelB] into RA, RB, and RC. Copy from Input Fetch to Input microaddress value 0x0. Set A1 with value 0x1 (Logical NOT of MUXC_MUXB). Copy from Wired Zero to Output of MUX C value 0x0.
Micropc at 0x0. Activated signals are: T2 C0. Associated actions are: Copy from Program Counter Register to Internal Bus value 0x8004. Load from Internal Bus to Memory Address Register value 0x8004.
Micropc at 0x1. Activated signals are: TA R BW M1 C1. Associated actions are: Copy from Memory Address Register to Address Bus value 0x8004. Memory output = 0x8600001 (Read a word from 0x8004). Select the full Word. Copy from from Memory to Input of Memory Data Register value 0x8600001. Load from Input of Memory Data Register to Memory Data Register value 0x8600001.
...
Micropc at 0x0. Activated signals are: T2 C0. Associated actions are: Copy from Program Counter Register to Internal Bus value 0x8000. Load from Internal Bus to Memory Address Register value 0x8000.
Micropc at 0x1. Activated signals are: TA R BW M1 C1. Associated actions are: Copy from Memory Address Register to Address Bus value 0x8000. Memory output = 0x8400002 (Read a word from 0x8000). Select the full Word. Copy from from Memory to Input of Memory Data Register value 0x8400002. Load from Input of Memory Data Register to Memory Data Register value 0x8400002.
Micropc at 0x2. Activated signals are: M2 C2 T1 C3. Associated actions are: Copy to Input of Program Counter Program Counter Register plus four with result 0x8004. Load from Input of Program Counter to Program Counter Register value 0x8004. Copy from Memory Data Register to Internal Bus value 0x8400002. Load from Internal Bus to Instruction Register value 0x8400002. Decode instruction.
Micropc at 0x3. Activated signals are: A0 B C. Associated actions are: Copy from Input ROM to Input microaddress value 0x67. Copy from Output of MUX C to A1 value 0x0. Copy from Wired Zero to Output of MUX C value 0x0.
Micropc at 0x67. Activated signals are: SE OFFSET SIZE T3 LC MR SELC A0 B C. Associated actions are: Copy from Instruction Register to Input of T3 Tristate value 0x2 (copied 16 bits from bit 0). Copy from Instruction Register to Input of T3 Tristate value 0x2 (copied 16 bits from bit 0). Copy from Instruction Register to Input of T3 Tristate value 0x2 (copied 16 bits from bit 0). Copy from Input of T3 Tristate to Internal Bus value 0x2. Copy to Register 2 the value 0x2. Copy from IR[SelA], from IR[SelB], and from IR[SelB] into RA, RB, and RC. Copy from Input Fetch to Input microaddress value 0x0. Set A1 with value 0x1 (Logical NOT of MUXC_MUXB). Copy from Wired Zero to Output of MUX C value 0x0.
Micropc at 0x0. Activated signals are: T2 C0. Associated actions are: Copy from Program Counter Register to Internal Bus value 0x8004. Load from Internal Bus to Memory Address Register value 0x8004.
Micropc at 0x1. Activated signals are: TA R BW M1 C1. Associated actions are: Copy from Memory Address Register to Address Bus value 0x8004. Memory output = 0x8600001 (Read a word from 0x8004). Select the full Word. Copy from from Memory to Input of Memory Data Register value 0x8600001. Load from Input of Memory Data Register to Memory Data Register value 0x8600001.
...
Getting Started: Developers
WepSIM Source Code
-
WepSIM GitHub Repository:
- Stable build: https://github.com/wepsim/wepsim
- Nightly build: https://github.com/acaldero/wepsim
-
The WepSIM architecture can be summarized in the following Figure (made by https://app.diagrams.net):
- If you want to use the WepSIM engine within your App, there is a WepSIM API in JavaScript available too. You will need to include the WepSIM engine in your proyect:
<script src="min.sim_all.js" >script><noscript>Your browser does not support JavaScript!</noscript>
<script src="min.wepsim_web.js">script><noscript>Your browser does not support JavaScript!noscript>
<script src="min.wepsim_web.js">script><noscript>Your browser does not support JavaScript!noscript>
- And then, one simple example of using this WepSIM API is the following:
/*
* Input: minimal firmware and minimal assembly code
*/
str_firmware = 'begin {\n' +
' fetch: (T2, C0),\n' +
' (TA, R, BW=11, M1=1, C1=1),\n' +
' (M2, C2, T1, C3),\n' +
' (A0, B=0, C=0)\n' +
'}\n' +
'nop {\n' +
' co=010110,\n' +
' nwords=1,\n' +
' {\n' +
' (A0=1, B=1, C=0)\n' +
' }\n' +
'}\n' +
'registers {\n' +
' 0=$zero,\n' +
' 29=$sp (stack_pointer)\n' +
'}\n' ;
str_assembly = '.text\n' +
'main: nop\n' ;
/*
* Code: Initialize WepSIM + reset + compile firmware + compile assembly + execute + get final state
*/
// 1) initialize WepSIM engine
var ret = simcore_init(false) ;
if (false != ret.ok) {
ret = simcore_init_hw('ep') ;
}
if (false != ret.ok) {
var ui_cb = {} ;
simcore_init_ui(ui_cb) ;
}
// 2) reset hardware
if (false != ret.ok) {
simcore_reset() ;
}
// 3) load firmware
if (false != ret.ok) {
ret = simcore_compile_firmware(str_firmware) ;
}
// 4) load assembly
if (false != ret.ok) {
ret = simcore_compile_assembly(str_assembly) ;
}
// 5) execute firmware-assembly
if (false != ret.ok) {
var options = {
instruction_limit: 1024,
cycles_limit: 10240
} ;
ret = simcore_execute_program(options) ;
}
// 6) show a final report
if (false != ret.ok) {
var state_obj = simcore_simstate_current2state() ;
ret.msg = simcore_simstate_state2checklist(state_obj, '') ;
}
/*
* Output: the final state (or error found)
*/
console.log(ret.msg) ;
* Input: minimal firmware and minimal assembly code
*/
str_firmware = 'begin {\n' +
' fetch: (T2, C0),\n' +
' (TA, R, BW=11, M1=1, C1=1),\n' +
' (M2, C2, T1, C3),\n' +
' (A0, B=0, C=0)\n' +
'}\n' +
'nop {\n' +
' co=010110,\n' +
' nwords=1,\n' +
' {\n' +
' (A0=1, B=1, C=0)\n' +
' }\n' +
'}\n' +
'registers {\n' +
' 0=$zero,\n' +
' 29=$sp (stack_pointer)\n' +
'}\n' ;
str_assembly = '.text\n' +
'main: nop\n' ;
/*
* Code: Initialize WepSIM + reset + compile firmware + compile assembly + execute + get final state
*/
// 1) initialize WepSIM engine
var ret = simcore_init(false) ;
if (false != ret.ok) {
ret = simcore_init_hw('ep') ;
}
if (false != ret.ok) {
var ui_cb = {} ;
simcore_init_ui(ui_cb) ;
}
// 2) reset hardware
if (false != ret.ok) {
simcore_reset() ;
}
// 3) load firmware
if (false != ret.ok) {
ret = simcore_compile_firmware(str_firmware) ;
}
// 4) load assembly
if (false != ret.ok) {
ret = simcore_compile_assembly(str_assembly) ;
}
// 5) execute firmware-assembly
if (false != ret.ok) {
var options = {
instruction_limit: 1024,
cycles_limit: 10240
} ;
ret = simcore_execute_program(options) ;
}
// 6) show a final report
if (false != ret.ok) {
var state_obj = simcore_simstate_current2state() ;
ret.msg = simcore_simstate_state2checklist(state_obj, '') ;
}
/*
* Output: the final state (or error found)
*/
console.log(ret.msg) ;
- The following fragment is an example of how to use WepSIM command-line within Google Colab cell:
!echo "(1/4) Installing pre-requisites..."
!npm install terser jq jshint yargs clear inquirer >& /dev/null
!echo "(2/4) Downloading WepSIM..."
!wget https://github.com/acaldero/wepsim/releases/download/v2.2.0/ wepsim-2.2.0.zip >& /dev/null
!unzip -o wepsim-2.2.0.zip >& /dev/null
!rm -fr wepsim-2.2.0.zip
!echo "(3/4) Executing WepSIM..."
!./wepsim-2.2.0/wepsim.sh -a stepbystep -m ep -f ./wepsim-2.2.0/examples/microcode/mc-ep_mips_base.txt -s ./wepsim-2.2.0/examples/assembly/asm-mips_s1e1.txt > ./result.csv
!rm -fr wepsim-2.2.0
!echo "(4/4) Showing execution trace as table..."
import pandas as pd
import io
df1 = pd.read_csv('./result.csv')
df1.columns = df1.columns.str.strip()
for item in df1.columns[:]:
df1[item].replace("\t","", inplace=True, regex=True)
df1
!npm install terser jq jshint yargs clear inquirer >& /dev/null
!echo "(2/4) Downloading WepSIM..."
!wget https://github.com/acaldero/wepsim/releases/download/v2.2.0/ wepsim-2.2.0.zip >& /dev/null
!unzip -o wepsim-2.2.0.zip >& /dev/null
!rm -fr wepsim-2.2.0.zip
!echo "(3/4) Executing WepSIM..."
!./wepsim-2.2.0/wepsim.sh -a stepbystep -m ep -f ./wepsim-2.2.0/examples/microcode/mc-ep_mips_base.txt -s ./wepsim-2.2.0/examples/assembly/asm-mips_s1e1.txt > ./result.csv
!rm -fr wepsim-2.2.0
!echo "(4/4) Showing execution trace as table..."
import pandas as pd
import io
df1 = pd.read_csv('./result.csv')
df1.columns = df1.columns.str.strip()
for item in df1.columns[:]:
df1[item].replace("\t","", inplace=True, regex=True)
df1
-
If you want to control a WepSIM instance, there is a WepSIM API in JavaScript available (WepSIM 2.0.6+). For example, It might be used for building a tutorial.
The following fragment uses the WepSIM control API (wsweb_*):
Step 1.- Load Example
Step 2.- Run
"> <div class="container"><nav class="nav nav-pills nav-justified">
<a href="#"
class="nav-item nav-link border border-secondary"
onclick="var context1 = document.getElementById('iframe1');
context1.src = 'https://acaldero.github.io/wepsim/ws_dist/wepsim-classic.ht ml?' +
'notify=false&' +
'example=13&' +
'simulator=assembly:screen';
return false;">Step 1.- Load Examplea>
<a href="#"
class="nav-item nav-link border border-secondary"
onclick="var context1 = document.getElementById('iframe1').contentWindow;
context1.wsweb_execution_run();
return false;">Step 2.- Runa>
nav>
<div class="row">
<div class="col-12">
<div class="embed-responsive embed-responsive-4by3">
<iframe class="w-100 border border-secondary embed-responsive-item"
id="iframe1" src="">iframe>
div>
div>
div>
div>