Compare commits

..

No commits in common. "5a28a554a1a5a9c31f74338cf80c9519f9a5cb47" and "3c0f5d34bf8241a55c4d791bd74170c80cf47ee0" have entirely different histories.

3 changed files with 82 additions and 95 deletions

View File

@ -2,21 +2,15 @@ module CacheSim.AccessView exposing (..)
import CacheSim.Cache exposing (..) import CacheSim.Cache exposing (..)
import CacheSim.Hierarchy exposing (..) import CacheSim.Hierarchy exposing (..)
type AccessPosition = Down Int | Up Int | Preview | End type AccessPosition = Down Int | Up Int | Done
type alias AccessView = type alias AccessView = (List (AccessEffect Cache), AccessPosition)
{ initialState : CacheHierarchy
, blockAddr : BlockAddr
, accessEffects : List (AccessEffect Cache)
, position : AccessPosition
}
accessPositionForward : Int -> AccessPosition -> AccessPosition accessPositionForward : Int -> AccessPosition -> AccessPosition
accessPositionForward depth av = accessPositionForward depth av =
case av of case av of
Down n -> if n == depth - 1 then Up n else Down (n + 1) Down n -> if n == depth - 1 then Up n else Down (n + 1)
Up n -> if n == 0 then Preview else Up (n - 1) Up n -> if n == 0 then Done else Up (n - 1)
Preview -> End Done -> Done
End -> End
accessPositionBack : Int -> AccessPosition -> AccessPosition accessPositionBack : Int -> AccessPosition -> AccessPosition
accessPositionBack depth av = accessPositionBack depth av =
@ -24,43 +18,41 @@ accessPositionBack depth av =
Down 0 -> Down 0 Down 0 -> Down 0
Down n -> Down (n-1) Down n -> Down (n-1)
Up n -> if n == (depth - 1) then Down n else Up (n + 1) Up n -> if n == (depth - 1) then Down n else Up (n + 1)
Preview -> Up 0 Done -> Up 0
End -> Preview
accessPositionDone : AccessPosition -> Bool accessPositionDone : AccessPosition -> Bool
accessPositionDone av = accessPositionDone av =
case av of case av of
End -> True Done -> True
_ -> False _ -> False
accessViewForward : AccessView -> AccessView accessViewForward : AccessView -> AccessView
accessViewForward av = { av | position = accessPositionForward (List.length av.accessEffects) av.position } accessViewForward (l, ap) = (l, accessPositionForward (List.length l) ap)
accessViewBack : AccessView -> AccessView accessViewBack : AccessView -> AccessView
accessViewBack av = { av | position = accessPositionBack (List.length av.accessEffects) av.position } accessViewBack (l, ap) = (l, accessPositionBack (List.length l) ap)
accessViewDone : AccessView -> Bool accessViewDone : AccessView -> Bool
accessViewDone av = accessPositionDone av.position accessViewDone (_, ap) = accessPositionDone ap
finalCacheHierarchy : AccessView -> CacheHierarchy finalCacheHierarchy : CacheHierarchy -> AccessView -> CacheHierarchy
finalCacheHierarchy av = finalCacheHierarchy ch (l, ap) =
List.map .output av.accessEffects ++ List.drop (List.length av.accessEffects) av.initialState List.map .output l ++ List.drop (List.length l) ch
effectiveCacheHierarchy : AccessView -> CacheHierarchy
effectiveCacheHierarchy av = effectiveCacheHierarchy : CacheHierarchy -> AccessView -> CacheHierarchy
effectiveCacheHierarchy c (l, ap) =
let let
finalContents = List.map .output av.accessEffects finalContents = List.map .output l
unaccessed = List.drop (List.length av.accessEffects) av.initialState unaccessed = List.drop (List.length l) c
notDone = notDone =
case av.position of case ap of
Preview -> [] Done -> []
End -> [] Down _ -> List.take (List.length l) c
Down _ -> List.take (List.length av.accessEffects) av.initialState Up n -> List.take n c
Up n -> List.take n av.initialState
done = done =
case av.position of case ap of
Preview -> finalContents Done -> finalContents
End -> finalContents
Down _ -> [] Down _ -> []
Up n -> List.drop n finalContents Up n -> List.drop n finalContents
in in

View File

@ -45,13 +45,8 @@ updateAccess li m =
case xs of case xs of
[] -> Ok [] [] -> Ok []
(i::t) -> (i::t) ->
case accessCacheHierarchy (i // 4) c of case accessCacheHierarchy i c of
Ok av -> Ok av -> Result.map ((::) (av, Down 0)) <| process (finalCacheHierarchy c (av, Done)) t
let
newView = { blockAddr = i, accessEffects = av, position = Down 0, initialState = c }
in
Result.map ((::) newView)
<| process (finalCacheHierarchy newView) t
Err s -> Err s Err s -> Err s
accessResult = Maybe.andThen (\h -> Result.toMaybe <| process h li) m.hierarchy accessResult = Maybe.andThen (\h -> Result.toMaybe <| process h li) m.hierarchy
@ -64,15 +59,12 @@ updateAccessViewForward : Model -> (Model, Cmd Msg)
updateAccessViewForward m = updateAccessViewForward m =
let let
afterStep = Maybe.map (intMapUpdate 0 accessViewForward) m.accessView afterStep = Maybe.map (intMapUpdate 0 accessViewForward) m.accessView
newAccessView = (newHierarchy, newAccessView) =
case afterStep of case afterStep of
Just (result::xs) -> Just ((avs, Done)::[]) -> (Maybe.map (\h -> finalCacheHierarchy h (avs, Done)) m.hierarchy, Nothing)
case (result.position, xs) of Just ((avs, Done)::xs) -> (Maybe.map (\h -> finalCacheHierarchy h (avs, Done)) m.hierarchy, Just xs)
(End, []) -> Nothing as_ -> (m.hierarchy, as_)
(End, nxs) -> Just nxs newModel = { m | accessView = newAccessView, hierarchy = newHierarchy }
_ -> Just (result::xs)
as_ -> as_
newModel = { m | accessView = newAccessView }
cmd = Cmd.none cmd = Cmd.none
in in
(newModel, cmd) (newModel, cmd)

View File

@ -10,31 +10,34 @@ import Html.Attributes exposing (type_, class, value, for, classList, disabled,
import Html.Events exposing (onInput, onClick) import Html.Events exposing (onInput, onClick)
-- Button components, powered by Bootstrap -- Button components, powered by Bootstrap
button : List (Attribute Msg) -> String -> Html Msg basicButton : List (Attribute Msg) -> String -> Html Msg
button attrs s = input ([ type_ "button", value s, class "btn"] ++ attrs) [] basicButton attrs s = input ([ type_ "button", value s, class "btn", class "btn-info" ] ++ attrs) []
basicButton : Msg -> String -> Html Msg disabledButton : String -> Html Msg
basicButton msg s = button [ onClick msg ] s disabledButton = basicButton [ disabled True ]
disabledButton : List (Attribute Msg) -> String -> Html Msg advancedButton : List (Attribute Msg) -> String -> Msg -> Html Msg
disabledButton attrs = button (attrs ++ [ disabled True ]) advancedButton attrs s m = basicButton (attrs ++ [ onClick m ]) s
button : String -> Msg -> Html Msg
button s m = basicButton [ onClick m ] s
dangerButton : String -> Msg -> Html Msg dangerButton : String -> Msg -> Html Msg
dangerButton s m = button [ onClick m, class "btn-danger" ] s dangerButton = advancedButton [ class "btn-danger" ]
primaryButton : String -> Msg -> Html Msg primaryButton : String -> Msg -> Html Msg
primaryButton s m = button [ onClick m, class "btn-primary" ] s primaryButton = advancedButton [ class "btn-primary" ]
secondaryButton : String -> Msg -> Html Msg secondaryButton : String -> Msg -> Html Msg
secondaryButton s m = button [ onClick m, class "btn-secondary" ] s secondaryButton = advancedButton [ class "btn-secondary" ]
maybeButton : Maybe a -> List (Attribute Msg) -> String -> (a -> Msg) -> Html Msg maybeButton : Maybe a -> String -> (a -> Msg) -> Html Msg
maybeButton m attrs s f = maybeButton m s f =
case m of case m of
Just v -> button (attrs ++ [ onClick (f v) ]) s Just v -> button s (f v)
_ -> disabledButton attrs s _ -> disabledButton s
resultButton : Result e a -> List (Attribute Msg) -> String -> (a -> Msg) -> Html Msg resultButton : Result e a -> String -> (a -> Msg) -> Html Msg
resultButton = maybeButton << Result.toMaybe resultButton = maybeButton << Result.toMaybe
-- Button wrapper (button group) -- Button wrapper (button group)
@ -102,8 +105,8 @@ viewRawCacheModelHierarchy rcmh =
Ok _ -> viewError True "" Ok _ -> viewError True ""
Err e -> viewError False e Err e -> viewError False e
newButton = primaryButton "Add level" CreateRawModel newButton = button "Add level" CreateRawModel
useButton = resultButton checkedResult [ class "btn-primary" ] "Start simulation" (UseHierarchy << Just) useButton = resultButton checkedResult "Use hierarchy" (UseHierarchy << Just)
in in
div [] div []
[ h2 [] [ text "Cache hierarchy" ] [ h2 [] [ text "Cache hierarchy" ]
@ -160,21 +163,23 @@ viewCacheHierarchy ch =
viewAccessView : Model -> AccessView -> Html Msg viewAccessView : Model -> AccessView -> Html Msg
viewAccessView m av = viewAccessView m av =
div [] let
[ h2 [] [ text "Access Simulation" ] currentCache = Maybe.withDefault [] m.hierarchy
, p [] [ text ("Simulating access of address " ++ String.fromInt av.blockAddr) ] in
, buttonWrapper div []
[ primaryButton "Back" AccessViewBack [ h2 [] [ text "Access Simulation" ]
, primaryButton "Forward" AccessViewForward , buttonWrapper
] [ primaryButton "Back" AccessViewBack
, h3 [] [ text "Access event log" ] , primaryButton "Forward" AccessViewForward
, viewAccessLog av ]
, h3 [] [ text "Current cache state" ] , h3 [] [ text "Access event log" ]
, viewCacheHierarchy <| effectiveCacheHierarchy av , viewAccessLog av
] , h3 [] [ text "Current cache state" ]
, viewCacheHierarchy <| effectiveCacheHierarchy currentCache av
]
viewAccessLog : AccessView -> Html Msg viewAccessLog : AccessView -> Html Msg
viewAccessLog av = viewAccessLog (aes, ap) =
let let
resultSpan r = resultSpan r =
span [ classList [ ("badge", True), ("badge-success", r == Hit), ("badge-danger", r == Miss) ] ] span [ classList [ ("badge", True), ("badge-success", r == Hit), ("badge-danger", r == Miss) ] ]
@ -184,17 +189,14 @@ viewAccessLog av =
, resultSpan ae.result , resultSpan ae.result
] ]
upEvent n ae = div [ class "event" ] upEvent n ae = div [ class "event" ]
[ text <| "Updated L" ++ String.fromInt (List.length av.accessEffects - n) [ text <| "Updated L" ++ String.fromInt (List.length aes - n)
] ]
events = events =
case av.position of case ap of
Preview -> List.indexedMap downEvent av.accessEffects ++ Done -> []
(List.indexedMap upEvent av.accessEffects) ++ Down n -> List.indexedMap downEvent <| List.take (n + 1) aes
[ div [ class "event" ] [ text "Access complete. Viewing final cache state." ] ] Up n -> List.indexedMap downEvent aes ++
End -> [] (List.indexedMap upEvent <| List.drop n aes)
Down n -> List.indexedMap downEvent <| List.take (n + 1) av.accessEffects
Up n -> List.indexedMap downEvent av.accessEffects ++
(List.indexedMap upEvent <| List.drop n av.accessEffects)
in in
div [] events div [] events
@ -202,26 +204,27 @@ viewAccessInput : Model -> Html Msg
viewAccessInput m = viewAccessInput m =
let let
parser = parser =
Parser.sequence Parser.map (List.map (\i -> i // 4)) <|
{ start = "" Parser.sequence
, end = "" { start = ""
, separator = "," , end = ""
, spaces = Parser.spaces , separator = ","
, item = Parser.int , spaces = Parser.spaces
, trailing = Parser.Optional , item = Parser.int
} , trailing = Parser.Optional
}
parseErrorToString _ = "Unable to parse input. Please enter a sequence of numbers separated by commas." parseErrorToString _ = "Unable to parse input. Please enter a sequence of numbers separated by commas."
parseResult = Parser.run (parser |. Parser.end) m.accessInput parseResult = Parser.run (parser |. Parser.end) m.accessInput
checkedResult = checkedResult =
case parseResult of case parseResult of
Ok is -> if is == [] then Err "Please enter at least one number." else Ok is Ok is -> if is == [] then Err "Please enter at least one number." else Ok is
Err e -> Err <| parseErrorToString e Err e -> Err <| parseErrorToString e
accessButton = resultButton checkedResult [ class "btn-primary" ] "Access address" Access accessButton = resultButton checkedResult "Access address" Access
errorHtml = errorHtml =
case checkedResult of case checkedResult of
Ok _ -> viewError True "" Ok _ -> viewError True ""
Err e -> viewError False e Err e -> viewError False e
editHierarchyButton = secondaryButton "Edit hierarchy" (UseHierarchy Nothing) editHierarchyButton = button "Edit hierarchy" (UseHierarchy Nothing)
in in
div [] div []
[ h2 [] [ text "Run access simulation" ] [ h2 [] [ text "Run access simulation" ]
@ -241,7 +244,7 @@ viewDescription =
, p [] , p []
[ text <| "To use the simulator, first create a fitting cache configuration by using the \"Add level\" button," [ text <| "To use the simulator, first create a fitting cache configuration by using the \"Add level\" button,"
++ " as well as the settings provided by each individual cache level. When the cache is correctly specified, and" ++ " as well as the settings provided by each individual cache level. When the cache is correctly specified, and"
++ " no warnings appear, click \"Start simulation\" to load the specified hierarchy and begin simulating. To simulate," ++ " no warnings appear, click \"Use hierarchy\" to load the specified hierarchy and begin simulating. To simulate,"
++ " type a block address into the \"Access address\" field, and click \"Access\". This will bring forward the simulation" ++ " type a block address into the \"Access address\" field, and click \"Access\". This will bring forward the simulation"
++ " view, which will allow you to step through the steps of accessing a cache." ++ " view, which will allow you to step through the steps of accessing a cache."
] ]