diff --git a/src/Renderer/Interface/FilesIO.fs b/src/Renderer/Interface/FilesIO.fs index a51335fcd..06dc1ee80 100644 --- a/src/Renderer/Interface/FilesIO.fs +++ b/src/Renderer/Interface/FilesIO.fs @@ -626,7 +626,7 @@ let checkMemoryContents (projectPath:string) (comp: Component) : Component = /// load a component from its canvas and other elements let makeLoadedComponentFromCanvasData (canvas: CanvasState) filePath timeStamp waveInfo (sheetInfo:SheetInfo option) = let projectPath = dirName filePath - let inputs, outputs = Extractor.parseDiagramSignature canvas + let inputs, outputs = CanvasExtractor.parseDiagramSignature canvas //printfn "parsed component" let comps,conns = canvas let comps' = List.map (checkMemoryContents projectPath) comps diff --git a/src/Renderer/Playground.fs b/src/Renderer/Playground.fs index 3ed8059b9..8f3c9d8a1 100644 --- a/src/Renderer/Playground.fs +++ b/src/Renderer/Playground.fs @@ -283,8 +283,8 @@ module Misc = let highLightChangedConnections dispatch = - dispatch (Sheet (SheetT.Msg.SelectWires Extractor.debugChangedConnections)) - Extractor.debugChangedConnections <- [] + dispatch (Sheet (SheetT.Msg.SelectWires CanvasExtractor.debugChangedConnections)) + CanvasExtractor.debugChangedConnections <- [] module Memory = open Fable.Core diff --git a/src/Renderer/Renderer.fsproj b/src/Renderer/Renderer.fsproj index ad90b2ede..7f258c5eb 100644 --- a/src/Renderer/Renderer.fsproj +++ b/src/Renderer/Renderer.fsproj @@ -28,7 +28,7 @@ - + @@ -96,6 +96,7 @@ + diff --git a/src/Renderer/Simulator/Extractor.fs b/src/Renderer/Simulator/CanvasExtractor.fs similarity index 99% rename from src/Renderer/Simulator/Extractor.fs rename to src/Renderer/Simulator/CanvasExtractor.fs index fc8772323..aa25b6bba 100644 --- a/src/Renderer/Simulator/Extractor.fs +++ b/src/Renderer/Simulator/CanvasExtractor.fs @@ -1,4 +1,4 @@ -module Extractor +module CanvasExtractor open CommonTypes open Fable.Core diff --git a/src/Renderer/Simulator/FastSim/FastExtract.fs b/src/Renderer/Simulator/FastSim/FastExtract.fs index 97554bb61..ac7070271 100644 --- a/src/Renderer/Simulator/FastSim/FastExtract.fs +++ b/src/Renderer/Simulator/FastSim/FastExtract.fs @@ -257,7 +257,7 @@ let extractViewers (simulationData: SimulationData) : ((string * string) * int * getFLabel fs fid, width, extractFastSimulationOutput fs simulationData.ClockTickNumber fid (OutputPortNumber 0)) let compareLoadedStates (fs: FastSimulation) (canv: CanvasState) (p: Project option) = - List.forall (fun ldc -> Extractor.loadedComponentIsSameAsProject canv ldc p) fs.SimulatedCanvasState + List.forall (fun ldc -> CanvasExtractor.loadedComponentIsSameAsProject canv ldc p) fs.SimulatedCanvasState /// Get the input value of a fast component as a bigint. /// fc: the fast component to get the input from. diff --git a/src/Renderer/Simulator/Simulator.fs b/src/Renderer/Simulator/Simulator.fs index 83613cf40..39c484766 100644 --- a/src/Renderer/Simulator/Simulator.fs +++ b/src/Renderer/Simulator/Simulator.fs @@ -12,7 +12,7 @@ open SynchronousUtils open GraphBuilder open GraphMerger open SimulationGraphAnalyser -open Extractor +open CanvasExtractor // Building a SimulationGraph has four phases (not precisely in order of execution): // 1. Building a simulation graph made of SimulationComponents. @@ -63,7 +63,7 @@ let rec sheetsNeeded (ldcs: LoadedComponent list) (sheet: string) : string list /// diagramName: name of current open sheet. /// return updated list of all LDCs let getUpdatedLoadedComponentState diagramName canvasState projLdcs = - let ldc' = Extractor.extractLoadedSimulatorComponent canvasState diagramName + let ldc' = CanvasExtractor.extractLoadedSimulatorComponent canvasState diagramName let ldcs = let ldcIsOpen ldc = ldc.Name = diagramName @@ -97,8 +97,8 @@ let getCurrentSimulationState List.tryFind (fun (ldc': LoadedComponent) -> ldc'.Name = ldc.Name) p.LoadedComponents with | _, None -> false - | false, Some ldc' -> Extractor.loadedComponentIsEqual ldc ldc' - | true, Some _ -> Extractor.stateIsEqual ldc.CanvasState canvState) + | false, Some ldc' -> CanvasExtractor.loadedComponentIsEqual ldc ldc' + | true, Some _ -> CanvasExtractor.stateIsEqual ldc.CanvasState canvState) match simIsUpToDate, p.OpenFileName = fs.SimulatedTopSheet with | false, _ -> SimOutOfDate diff --git a/src/Renderer/UI/CatalogueView.fs b/src/Renderer/UI/CatalogueView.fs index 00bb11d25..43f91b380 100644 --- a/src/Renderer/UI/CatalogueView.fs +++ b/src/Renderer/UI/CatalogueView.fs @@ -58,8 +58,8 @@ let private makeCustom styles model dispatch (loadedComponent: LoadedComponent) menuItem styles loadedComponent.Name (fun _ -> let custom = Custom { Name = loadedComponent.Name - InputLabels = Extractor.getOrderedCompLabels (Input1 (0, None)) canvas - OutputLabels = Extractor.getOrderedCompLabels (Output 0) canvas + InputLabels = CanvasExtractor.getOrderedCompLabels (Input1 (0, None)) canvas + OutputLabels = CanvasExtractor.getOrderedCompLabels (Output 0) canvas Form = loadedComponent.Form Description = loadedComponent.Description } @@ -87,8 +87,8 @@ let private makeVerilog styles model dispatch (loadedComponent: LoadedComponent) menuItem styles loadedComponent.Name (fun _ -> let verilog = Custom { Name = loadedComponent.Name - InputLabels = Extractor.getOrderedCompLabels (Input1 (0, None)) canvas - OutputLabels = Extractor.getOrderedCompLabels (Output 0) canvas + InputLabels = CanvasExtractor.getOrderedCompLabels (Input1 (0, None)) canvas + OutputLabels = CanvasExtractor.getOrderedCompLabels (Output 0) canvas Form = loadedComponent.Form Description = loadedComponent.Description } diff --git a/src/Renderer/UI/CustomCompPorts.fs b/src/Renderer/UI/CustomCompPorts.fs index 687afb848..be09dcbf5 100644 --- a/src/Renderer/UI/CustomCompPorts.fs +++ b/src/Renderer/UI/CustomCompPorts.fs @@ -19,7 +19,7 @@ open ModelType open ModelHelpers open CommonTypes open FilesIO -open Extractor +open CanvasExtractor open PopupHelpers open MenuHelpers diff --git a/src/Renderer/UI/MainView.fs b/src/Renderer/UI/MainView.fs index 44a3d2c34..5c4afb7d4 100644 --- a/src/Renderer/UI/MainView.fs +++ b/src/Renderer/UI/MainView.fs @@ -136,7 +136,7 @@ let viewSimSubTab canvasState model dispatch = | StepSim -> div [ Style [Width "90%"; MarginLeft "5%"; MarginTop "15px" ] ] [ Heading.h4 [] [ str "Step Simulation" ] - SimulationView.viewSimulation canvasState model dispatch + StepSimulationTop.viewSimulation canvasState model dispatch ] | TruthTable -> div [ Style [Width "90%"; MarginLeft "5%"; MarginTop "15px" ] ] [ diff --git a/src/Renderer/UI/MenuHelpers.fs b/src/Renderer/UI/MenuHelpers.fs index 20f721c02..2e9e62a36 100644 --- a/src/Renderer/UI/MenuHelpers.fs +++ b/src/Renderer/UI/MenuHelpers.fs @@ -12,7 +12,7 @@ open ModelType open ModelHelpers open CommonTypes open FilesIO -open Extractor +open CanvasExtractor open Notifications open PopupHelpers open DrawModelType diff --git a/src/Renderer/UI/MiscMenuView.fs b/src/Renderer/UI/MiscMenuView.fs index 11baf0a65..b622c75c0 100644 --- a/src/Renderer/UI/MiscMenuView.fs +++ b/src/Renderer/UI/MiscMenuView.fs @@ -10,7 +10,7 @@ open CommonTypes open ModelType open ModelHelpers open MenuHelpers -open Extractor +open CanvasExtractor open FilesIO open PopupHelpers open DrawModelType diff --git a/src/Renderer/UI/SimulationView.fs b/src/Renderer/UI/SimulationView.fs index dcd5564aa..badc43a24 100644 --- a/src/Renderer/UI/SimulationView.fs +++ b/src/Renderer/UI/SimulationView.fs @@ -23,7 +23,7 @@ open MemoryEditorView open ModelType open CommonTypes open SimulatorTypes -open Extractor +open CanvasExtractor open Simulator open Sheet.SheetInterface open DrawModelType @@ -709,7 +709,7 @@ let simulationClockChangeAction dispatch simData (model': Model) = -let private viewSimulationData (step: int) (simData : SimulationData) model dispatch = +let viewSimulationData (step: int) (simData : SimulationData) model dispatch = let viewerWidthList = FastExtract.extractViewers simData |> List.map (fun (_, width, _) -> width) @@ -852,260 +852,3 @@ let tryGetSimData isWaveSim canvasState model = printfn $"ERROR:{simError}" Error simError -let viewSimulation canvasState model dispatch = - /// This is the top-level function that creates a new fast simulation for the step simulator. - let startSimulation model _ = - // make sure simulation runs with uptodate memory contents based on linked files. - // memory in model is not updated because the model update will be lost. This does - // matter because if memory contents are ever viewed the viewer will update them then. - let model = MemoryEditorView.updateAllMemoryComps model - tryGetSimData false canvasState model - |> function - | Ok simData -> - Ok simData - | Error simError -> - setSimErrorFeedback simError model dispatch - Error simError - |> StartSimulation - |> dispatch - match model.CurrentProj with - | Some project -> - let loadedDependencies = project.LoadedComponents |> List.filter (fun comp -> comp.Name <> project.OpenFileName) - let ldcs = addStateToLoadedComponents simCache.Name canvasState loadedDependencies - simCache <- {simCache with StoredState = ldcs} - | None -> () - - let hasCanvasChanged - (currentCanvasState) - (simCache) - (model) - : bool = - match model.CurrentProj with - | Some project -> - let loadedDependencies = project.LoadedComponents |> List.filter (fun comp -> comp.Name <> project.OpenFileName) - let ldcs = addStateToLoadedComponents simCache.Name currentCanvasState loadedDependencies - let isSame = storedstateisEqual simCache ldcs - not isSame - | _ -> false - - let simRes = simulateModel false None Constants.maxArraySize canvasState model - // let JSState = model.Diagram.GetCanvasState () - match model.CurrentStepSimulationStep with - | None -> - let isSync = match simRes with | Ok {IsSynchronous=true},_ -> true | _ -> false - let buttonColor, buttonText = - match simRes with - | Ok _, _ -> IsSuccess, "Start Simulation" - | Error _, _ -> IsWarning, "See Problems" - div [] [ - str "Simulate simple logic using this tab." - br [] - str (if isSync then "You can also use the Wave Simulation tab to view waveforms" else "") - br []; br [] - Button.button - [ - Button.Color buttonColor; - Button.OnClick (fun _ -> dispatch <| ExecFuncInMessage(startSimulation, dispatch)) ; - ] - [ str buttonText ] - ] - | Some sim -> - let canvasStateChange = hasCanvasChanged canvasState simCache model - let body = match sim with - | Error simError -> viewSimulationError canvasState simError model StepSim dispatch - | Ok simData -> - if simCache.RestartSim then - let clock = simData.ClockTickNumber - startSimulation model () - simCache <- {simCache with RestartSim = false} - simCache <- {simCache with ClockTickRefresh = clock} - if (simData.ClockTickNumber = 0 && not (simCache.ClockTickRefresh = 0)) then - IncrementSimulationClockTick simCache.ClockTickRefresh |> dispatch - FastRun.runFastSimulation None simCache.ClockTickRefresh simData.FastSim |> ignore - simCache <- {simCache with ClockTickRefresh = 0} - viewSimulationData simData.ClockTickNumber simData model dispatch - let setDefaultButton = - match sim with - | Error _ -> div [] [] - | Ok simData -> - Button.button - [ - Button.Color IsInfo; - Button.Disabled (InputDefaultsEqualInputs simData.FastSim model simData.ClockTickNumber) - Button.OnClick (fun _ -> setInputDefaultsFromInputs simData.FastSim dispatch simData.ClockTickNumber) ; - Button.Props [Style [Display DisplayOptions.Inline; Float FloatOptions.Right ]] - ] - [ str "Save current input values as default" ] - - let confirmRefreshPopup (model:Model) dispatch (simData: SimulationData) = - fun (model:Model) -> - div [] - [ - div [Style [Height "60px"; Display DisplayOptions.Block; MarginBottom "5px"]] [ - h6 [Style [Width "80%"; Float FloatOptions.Left;]] [str $"Refresh the simulation using current values of the inputs and the latest design? - The current values will be used as default for future simulations."] - Button.button [ - Button.Color IsSuccess - Button.OnClick (fun _ -> - setInputDefaultsFromInputs simData.FastSim dispatch simData.ClockTickNumber - simCache <- {simCache with RestartSim = true} - ClosePopup |> dispatch - ) - Button.Props [Style [Display DisplayOptions.Inline; Float FloatOptions.Right; MarginTop "10px";]] - ] [ str "Ok" ]] - hr [Style [Width "100%"; Float FloatOptions.Left;]] - div [Style [Height "50px"; Display DisplayOptions.Block;]] [ - h6 [Style [Width "80%"; Float FloatOptions.Left ]] [str $"Refresh the simulation using default values of inputs, current values will be lost."] - Button.button [ - Button.Color IsInfo - Button.OnClick (fun _ -> - let clock = simData.ClockTickNumber - startSimulation model dispatch - simCache <- {simCache with ClockTickRefresh = clock} - ClosePopup |> dispatch - ) - Button.Props [Style [Display DisplayOptions.Inline; Float FloatOptions.Right ]] - ] [ str "Reset" ]] - ] - - let buttonColor, buttonIcon = - match simRes with - | Ok _, _ -> IsSuccess, refreshSvg "white" "20px" - | Error _, _ -> IsWarning, str "See Problems" - - let createRefreshButton buttonColor buttonIcon onClick = - Button.button [ - Button.Color buttonColor; - Button.OnClick onClick - Button.Props [Style [Display DisplayOptions.Inline; Float FloatOptions.None; MarginLeft "5px"]] - ] [buttonIcon] - - let startSimulationUpdateCache clock = - startSimulation model () - simCache <- { simCache with ClockTickRefresh = clock } - - let createRefreshButtonForSimData sim model dispatch = - match sim with - | Ok (simData: SimulationData) -> - if InputDefaultsEqualInputsRefresh simData.FastSim model then - createRefreshButton buttonColor buttonIcon (fun _ -> - let clock = simData.ClockTickNumber - startSimulationUpdateCache clock) - else - createRefreshButton buttonColor buttonIcon (fun _ -> - match simRes with - | Ok _, _ -> - dialogPopupRefresh - "Refresh" - (confirmRefreshPopup model dispatch simData) - [] - dispatch - | Error _, _ -> startSimulationUpdateCache simData.ClockTickNumber) - | _ -> emptyRefreshSVG - - let createRefreshButtonError = - createRefreshButton buttonColor buttonIcon (fun _ -> - let clock = simCache.ClockTickRefresh - startSimulationUpdateCache clock) - - let refreshButton = - match canvasStateChange, sim with - | true, Ok _ -> createRefreshButtonForSimData sim model dispatch - | true, Error _ -> createRefreshButtonError - | _ -> emptyRefreshSVG - - div [Style [Height "100%"]] [ - div [Style [Height "40px"]] [ - Button.button - [ - Button.Color IsDanger; - Button.OnClick (fun _ -> - simReset dispatch - dispatch EndSimulation); - Button.Props [Style [Display DisplayOptions.Inline; Float FloatOptions.Left;]]] - [ str "End simulation" ] - refreshButton - setDefaultButton - ] - br []; - div [Style [Display DisplayOptions.Block;]] [] - str "The simulation uses the diagram as it was at the moment of - pressing the \"Start simulation\" or \"Refresh\" button using default input values." - hr [] - body - ] - -let tryStartSimulationAfterErrorFix (simType:SimSubTab) (model:Model) = - let withMsg msg model = model, Cmd.ofMsg msg - let withMsgs msgs model = model, Cmd.batch (msgs |> List.map Cmd.ofMsg) - let withCmdTTMsg ttMsg model = model, Cmd.ofMsg (TruthTableMsg ttMsg) - let conns = BusWire.extractConnections model.Sheet.Wire - let comps = SymbolUpdate.extractComponents model.Sheet.Wire.Symbol - let canvasState = comps,conns - let simErrFeedback simErr otherMsg = - (getSimErrFeedbackMessages simErr model) @ [otherMsg] - - match simType with - | StepSim -> - tryGetSimData false canvasState model - |> function - | Ok (simData) -> - model - |> set currentStepSimulationStep_ (simData |> Ok |> Some) - |> withMsg (StartSimulation (Ok simData)) - | Error simError -> - model - |> set currentStepSimulationStep_ (simError |> Error |> Some) - |> withMsgs (simErrFeedback simError (StartSimulation (Error simError))) - - | TruthTable -> - simulateModel false None 2 canvasState model - |> function - | Ok (simData), state -> - if simData.IsSynchronous = false then - model - |> set currentStepSimulationStep_ (simData |> Ok |> Some) - |> withCmdTTMsg (GenerateTruthTable (Some (Ok simData, state))) - else - { model with CurrentStepSimulationStep = None } - |> withCmdTTMsg CloseTruthTable - | Error simError, state -> - let feedbackMsg = GenerateTruthTable (Some (Error simError, state)) |> TruthTableMsg - model - |> set currentStepSimulationStep_ (simError |> Error |> Some) - |> withMsgs (simErrFeedback simError feedbackMsg) - - | WaveSim -> - let model = MemoryEditorView.updateAllMemoryComps model - let wsSheet = - match model.WaveSimSheet with - | None -> Option.get (getCurrFile model) - | Some sheet -> sheet - let model = - model - |> removeAllSimulationsFromModel - |> fun model -> {model with WaveSimSheet = Some wsSheet} - let wsModel = getWSModel model - //printfn $"simSheet={wsSheet}, wsModel sheet = {wsModel.TopSheet},{wsModel.FastSim.SimulatedTopSheet}, state={wsModel.State}" - match simulateModel - true - model.WaveSimSheet - (wsModel.WSConfig.LastClock + Constants.maxStepsOverflow) - canvasState - model with - - | (Error simError, _) -> - model - |> set currentStepSimulationStep_ (simError |> Error |> Some) - |> withMsgs (simErrFeedback simError (SetWSModelAndSheet ({ wsModel with State = SimError simError }, wsSheet))) - | (Ok simData, canvState) -> - if simData.IsSynchronous then - setFastSimInputsToDefault simData.FastSim - let wsModel = { wsModel with State = Loading} - model - |> set currentStepSimulationStep_ (simData |> Ok |> Some) - |> withMsgs [SetWSModelAndSheet (wsModel, wsSheet) ; RefreshWaveSim wsModel] - else - model - |> set currentStepSimulationStep_ (simData |> Ok |> Some) - |> withMsg (SetWSModelAndSheet ({ wsModel with State = NonSequential }, wsSheet)) diff --git a/src/Renderer/UI/StepSimulationTop.fs b/src/Renderer/UI/StepSimulationTop.fs new file mode 100644 index 000000000..8a3bafb0d --- /dev/null +++ b/src/Renderer/UI/StepSimulationTop.fs @@ -0,0 +1,281 @@ +module StepSimulationTop + +open Fulma +open Fulma.Extensions.Wikiki +open Fable.React +open Fable.React.Props +open Elmish + +open DiagramStyle +open Notifications +open PopupHelpers +open ModelType +open CommonTypes +open SimulatorTypes +open CanvasExtractor +open Simulator +open ModelHelpers +open Optics +open Optics.Optic +open Optics.Operators +open SimulationView + +let viewSimulation canvasState model dispatch = + /// This is the top-level function that creates a new fast simulation for the step simulator. + let startSimulation model _ = + // make sure simulation runs with uptodate memory contents based on linked files. + // memory in model is not updated because the model update will be lost. This does + // matter because if memory contents are ever viewed the viewer will update them then. + let model = MemoryEditorView.updateAllMemoryComps model + tryGetSimData false canvasState model + |> function + | Ok simData -> + Ok simData + | Error simError -> + setSimErrorFeedback simError model dispatch + Error simError + |> StartSimulation + |> dispatch + match model.CurrentProj with + | Some project -> + let loadedDependencies = project.LoadedComponents |> List.filter (fun comp -> comp.Name <> project.OpenFileName) + let ldcs = addStateToLoadedComponents simCache.Name canvasState loadedDependencies + simCache <- {simCache with StoredState = ldcs} + | None -> () + + let hasCanvasChanged + (currentCanvasState) + (simCache) + (model) + : bool = + match model.CurrentProj with + | Some project -> + let loadedDependencies = project.LoadedComponents |> List.filter (fun comp -> comp.Name <> project.OpenFileName) + let ldcs = addStateToLoadedComponents simCache.Name currentCanvasState loadedDependencies + let isSame = storedstateisEqual simCache ldcs + not isSame + | _ -> false + + let simRes = simulateModel false None Constants.maxArraySize canvasState model + // let JSState = model.Diagram.GetCanvasState () + match model.CurrentStepSimulationStep with + | None -> + let isSync = match simRes with | Ok {IsSynchronous=true},_ -> true | _ -> false + let buttonColor, buttonText = + match simRes with + | Ok _, _ -> IsSuccess, "Start Simulation" + | Error _, _ -> IsWarning, "See Problems" + div [] [ + str "Simulate simple logic using this tab." + br [] + str (if isSync then "You can also use the Wave Simulation tab to view waveforms" else "") + br []; br [] + Button.button + [ + Button.Color buttonColor; + Button.OnClick (fun _ -> dispatch <| ExecFuncInMessage(startSimulation, dispatch)) ; + ] + [ str buttonText ] + ] + | Some sim -> + let canvasStateChange = hasCanvasChanged canvasState simCache model + let body = match sim with + | Error simError -> viewSimulationError canvasState simError model StepSim dispatch + | Ok simData -> + if simCache.RestartSim then + let clock = simData.ClockTickNumber + startSimulation model () + simCache <- {simCache with RestartSim = false} + simCache <- {simCache with ClockTickRefresh = clock} + if (simData.ClockTickNumber = 0 && not (simCache.ClockTickRefresh = 0)) then + IncrementSimulationClockTick simCache.ClockTickRefresh |> dispatch + FastRun.runFastSimulation None simCache.ClockTickRefresh simData.FastSim |> ignore + simCache <- {simCache with ClockTickRefresh = 0} + viewSimulationData simData.ClockTickNumber simData model dispatch + let setDefaultButton = + match sim with + | Error _ -> div [] [] + | Ok simData -> + Button.button + [ + Button.Color IsInfo; + Button.Disabled (InputDefaultsEqualInputs simData.FastSim model simData.ClockTickNumber) + Button.OnClick (fun _ -> setInputDefaultsFromInputs simData.FastSim dispatch simData.ClockTickNumber) ; + Button.Props [Style [Display DisplayOptions.Inline; Float FloatOptions.Right ]] + ] + [ str "Save current input values as default" ] + + let confirmRefreshPopup (model:Model) dispatch (simData: SimulationData) = + fun (model:Model) -> + div [] + [ + div [Style [Height "60px"; Display DisplayOptions.Block; MarginBottom "5px"]] [ + h6 [Style [Width "80%"; Float FloatOptions.Left;]] [str $"Refresh the simulation using current values of the inputs and the latest design? + The current values will be used as default for future simulations."] + Button.button [ + Button.Color IsSuccess + Button.OnClick (fun _ -> + setInputDefaultsFromInputs simData.FastSim dispatch simData.ClockTickNumber + simCache <- {simCache with RestartSim = true} + ClosePopup |> dispatch + ) + Button.Props [Style [Display DisplayOptions.Inline; Float FloatOptions.Right; MarginTop "10px";]] + ] [ str "Ok" ]] + hr [Style [Width "100%"; Float FloatOptions.Left;]] + div [Style [Height "50px"; Display DisplayOptions.Block;]] [ + h6 [Style [Width "80%"; Float FloatOptions.Left ]] [str $"Refresh the simulation using default values of inputs, current values will be lost."] + Button.button [ + Button.Color IsInfo + Button.OnClick (fun _ -> + let clock = simData.ClockTickNumber + startSimulation model dispatch + simCache <- {simCache with ClockTickRefresh = clock} + ClosePopup |> dispatch + ) + Button.Props [Style [Display DisplayOptions.Inline; Float FloatOptions.Right ]] + ] [ str "Reset" ]] + ] + + let buttonColor, buttonIcon = + match simRes with + | Ok _, _ -> IsSuccess, refreshSvg "white" "20px" + | Error _, _ -> IsWarning, str "See Problems" + + let createRefreshButton buttonColor buttonIcon onClick = + Button.button [ + Button.Color buttonColor; + Button.OnClick onClick + Button.Props [Style [Display DisplayOptions.Inline; Float FloatOptions.None; MarginLeft "5px"]] + ] [buttonIcon] + + let startSimulationUpdateCache clock = + startSimulation model () + simCache <- { simCache with ClockTickRefresh = clock } + + let createRefreshButtonForSimData sim model dispatch = + match sim with + | Ok (simData: SimulationData) -> + if InputDefaultsEqualInputsRefresh simData.FastSim model then + createRefreshButton buttonColor buttonIcon (fun _ -> + let clock = simData.ClockTickNumber + startSimulationUpdateCache clock) + else + createRefreshButton buttonColor buttonIcon (fun _ -> + match simRes with + | Ok _, _ -> + dialogPopupRefresh + "Refresh" + (confirmRefreshPopup model dispatch simData) + [] + dispatch + | Error _, _ -> startSimulationUpdateCache simData.ClockTickNumber) + | _ -> emptyRefreshSVG + + let createRefreshButtonError = + createRefreshButton buttonColor buttonIcon (fun _ -> + let clock = simCache.ClockTickRefresh + startSimulationUpdateCache clock) + + let refreshButton = + match canvasStateChange, sim with + | true, Ok _ -> createRefreshButtonForSimData sim model dispatch + | true, Error _ -> createRefreshButtonError + | _ -> emptyRefreshSVG + + div [Style [Height "100%"]] [ + div [Style [Height "40px"]] [ + Button.button + [ + Button.Color IsDanger; + Button.OnClick (fun _ -> + simReset dispatch + dispatch EndSimulation); + Button.Props [Style [Display DisplayOptions.Inline; Float FloatOptions.Left;]]] + [ str "End simulation" ] + refreshButton + setDefaultButton + ] + br []; + div [Style [Display DisplayOptions.Block;]] [] + str "The simulation uses the diagram as it was at the moment of + pressing the \"Start simulation\" or \"Refresh\" button using default input values." + hr [] + body + ] + +let tryStartSimulationAfterErrorFix (simType:SimSubTab) (model:Model) = + let withMsg msg model = model, Cmd.ofMsg msg + let withMsgs msgs model = model, Cmd.batch (msgs |> List.map Cmd.ofMsg) + let withCmdTTMsg ttMsg model = model, Cmd.ofMsg (TruthTableMsg ttMsg) + let conns = BusWire.extractConnections model.Sheet.Wire + let comps = SymbolUpdate.extractComponents model.Sheet.Wire.Symbol + let canvasState = comps,conns + let simErrFeedback simErr otherMsg = + (getSimErrFeedbackMessages simErr model) @ [otherMsg] + + match simType with + | StepSim -> + tryGetSimData false canvasState model + |> function + | Ok (simData) -> + model + |> set currentStepSimulationStep_ (simData |> Ok |> Some) + |> withMsg (StartSimulation (Ok simData)) + | Error simError -> + model + |> set currentStepSimulationStep_ (simError |> Error |> Some) + |> withMsgs (simErrFeedback simError (StartSimulation (Error simError))) + + | TruthTable -> + simulateModel false None 2 canvasState model + |> function + | Ok (simData), state -> + if simData.IsSynchronous = false then + model + |> set currentStepSimulationStep_ (simData |> Ok |> Some) + |> withCmdTTMsg (GenerateTruthTable (Some (Ok simData, state))) + else + { model with CurrentStepSimulationStep = None } + |> withCmdTTMsg CloseTruthTable + | Error simError, state -> + let feedbackMsg = GenerateTruthTable (Some (Error simError, state)) |> TruthTableMsg + model + |> set currentStepSimulationStep_ (simError |> Error |> Some) + |> withMsgs (simErrFeedback simError feedbackMsg) + + | WaveSim -> + let model = MemoryEditorView.updateAllMemoryComps model + let wsSheet = + match model.WaveSimSheet with + | None -> Option.get (getCurrFile model) + | Some sheet -> sheet + let model = + model + |> removeAllSimulationsFromModel + |> fun model -> {model with WaveSimSheet = Some wsSheet} + let wsModel = getWSModel model + //printfn $"simSheet={wsSheet}, wsModel sheet = {wsModel.TopSheet},{wsModel.FastSim.SimulatedTopSheet}, state={wsModel.State}" + match simulateModel + true + model.WaveSimSheet + (wsModel.WSConfig.LastClock + Constants.maxStepsOverflow) + canvasState + model with + + | (Error simError, _) -> + model + |> set currentStepSimulationStep_ (simError |> Error |> Some) + |> withMsgs (simErrFeedback simError (SetWSModelAndSheet ({ wsModel with State = SimError simError }, wsSheet))) + | (Ok simData, canvState) -> + if simData.IsSynchronous then + setFastSimInputsToDefault simData.FastSim + let wsModel = { wsModel with State = Loading} + model + |> set currentStepSimulationStep_ (simData |> Ok |> Some) + |> withMsgs [SetWSModelAndSheet (wsModel, wsSheet) ; RefreshWaveSim wsModel] + else + model + |> set currentStepSimulationStep_ (simData |> Ok |> Some) + |> withMsg (SetWSModelAndSheet ({ wsModel with State = NonSequential }, wsSheet)) + + diff --git a/src/Renderer/UI/TopMenuView.fs b/src/Renderer/UI/TopMenuView.fs index 2b5c41689..dbe2a14c2 100644 --- a/src/Renderer/UI/TopMenuView.fs +++ b/src/Renderer/UI/TopMenuView.fs @@ -18,7 +18,7 @@ open ModelType open ModelHelpers open CommonTypes open FilesIO -open Extractor +open CanvasExtractor open Notifications open PopupHelpers open DrawModelType diff --git a/src/Renderer/UI/TruthTable/ConstraintReduceView.fs b/src/Renderer/UI/TruthTable/ConstraintReduceView.fs index 8216b0b3f..d2936db5f 100644 --- a/src/Renderer/UI/TruthTable/ConstraintReduceView.fs +++ b/src/Renderer/UI/TruthTable/ConstraintReduceView.fs @@ -24,7 +24,7 @@ open ModelType open CommonTypes open SimulatorTypes open TruthTableTypes -open Extractor +open CanvasExtractor open Simulator open TruthTableCreate open TruthTableReduce diff --git a/src/Renderer/UI/TruthTable/TruthTableView.fs b/src/Renderer/UI/TruthTable/TruthTableView.fs index 66596c153..d4b919a63 100644 --- a/src/Renderer/UI/TruthTable/TruthTableView.fs +++ b/src/Renderer/UI/TruthTable/TruthTableView.fs @@ -26,7 +26,7 @@ open CommonTypes open SimulatorTypes open TruthTableTypes open ConstraintReduceView -open Extractor +open CanvasExtractor open Simulator open TruthTableCreate open TruthTableReduce diff --git a/src/Renderer/UI/Update.fs b/src/Renderer/UI/Update.fs index a155ee7aa..1a7e99902 100644 --- a/src/Renderer/UI/Update.fs +++ b/src/Renderer/UI/Update.fs @@ -274,7 +274,7 @@ let update (msg : Msg) oldModel = |> withNoMsg | TryStartSimulationAfterErrorFix simType -> - SimulationView.tryStartSimulationAfterErrorFix simType model + StepSimulationTop.tryStartSimulationAfterErrorFix simType model | SetSimulationGraph (graph, fastSim) -> let simData = diff --git a/src/Renderer/UI/UpdateHelpers.fs b/src/Renderer/UI/UpdateHelpers.fs index eb234fe6d..19200b6f9 100644 --- a/src/Renderer/UI/UpdateHelpers.fs +++ b/src/Renderer/UI/UpdateHelpers.fs @@ -10,7 +10,7 @@ open SimulatorTypes open ModelType open ModelHelpers open CommonTypes -open Extractor +open CanvasExtractor open MenuHelpers open TopMenuView open Sheet.SheetInterface @@ -793,7 +793,7 @@ let findChange (model : Model) : bool = |> List.find (fun lc -> lc.Name = prj.OpenFileName) let canv = savedComponent.CanvasState let canv' = model.Sheet.GetCanvasState () - (canv <> canv') && not (compareCanvas 100. canv canv') + (canv <> canv') && not (CanvasExtractor.compareCanvas 100. canv canv') //|> TimeHelpers.instrumentInterval "findChange" start /// Needed so that constant properties selection will work diff --git a/src/Renderer/VerilogComponent/TestParser.fs b/src/Renderer/VerilogComponent/TestParser.fs index ef8950742..f0831593b 100644 --- a/src/Renderer/VerilogComponent/TestParser.fs +++ b/src/Renderer/VerilogComponent/TestParser.fs @@ -196,8 +196,8 @@ let simulateAST ast src dst loadedComps= // same order as in Verilog input let verilog = { Name = loadedComp.Name - InputLabels = Extractor.getOrderedCompLabels (Input1 (0, None)) cs - OutputLabels = Extractor.getOrderedCompLabels (Output 0) cs + InputLabels = CanvasExtractor.getOrderedCompLabels (Input1 (0, None)) cs + OutputLabels = CanvasExtractor.getOrderedCompLabels (Output 0) cs Form = loadedComp.Form Description = loadedComp.Description }