Compare commits
	
		
			2 Commits
		
	
	
		
			3c0f5d34bf
			...
			5a28a554a1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 5a28a554a1 | |||
| e6c7638324 | 
@ -2,15 +2,21 @@ 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 | Done
 | 
					type AccessPosition = Down Int | Up Int | Preview | End
 | 
				
			||||||
type alias AccessView = (List (AccessEffect Cache), AccessPosition)
 | 
					type alias AccessView =
 | 
				
			||||||
 | 
					    { 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 Done else Up (n - 1)
 | 
					        Up n -> if n == 0 then Preview else Up (n - 1)
 | 
				
			||||||
        Done -> Done
 | 
					        Preview -> End
 | 
				
			||||||
 | 
					        End -> End
 | 
				
			||||||
 | 
					
 | 
				
			||||||
accessPositionBack : Int -> AccessPosition -> AccessPosition
 | 
					accessPositionBack : Int -> AccessPosition -> AccessPosition
 | 
				
			||||||
accessPositionBack depth av =
 | 
					accessPositionBack depth av =
 | 
				
			||||||
@ -18,41 +24,43 @@ 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)
 | 
				
			||||||
        Done -> Up 0
 | 
					        Preview -> Up 0
 | 
				
			||||||
 | 
					        End -> Preview
 | 
				
			||||||
 | 
					
 | 
				
			||||||
accessPositionDone : AccessPosition -> Bool
 | 
					accessPositionDone : AccessPosition -> Bool
 | 
				
			||||||
accessPositionDone av =
 | 
					accessPositionDone av =
 | 
				
			||||||
    case av of
 | 
					    case av of
 | 
				
			||||||
        Done -> True
 | 
					        End -> True
 | 
				
			||||||
        _ -> False
 | 
					        _ -> False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
accessViewForward : AccessView -> AccessView
 | 
					accessViewForward : AccessView -> AccessView
 | 
				
			||||||
accessViewForward (l, ap) = (l, accessPositionForward (List.length l) ap)
 | 
					accessViewForward av = { av | position = accessPositionForward (List.length av.accessEffects) av.position }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
accessViewBack : AccessView -> AccessView
 | 
					accessViewBack : AccessView -> AccessView
 | 
				
			||||||
accessViewBack (l, ap) = (l, accessPositionBack (List.length l) ap)
 | 
					accessViewBack av = { av | position = accessPositionBack (List.length av.accessEffects) av.position }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
accessViewDone : AccessView -> Bool
 | 
					accessViewDone : AccessView -> Bool
 | 
				
			||||||
accessViewDone (_, ap) = accessPositionDone ap
 | 
					accessViewDone av = accessPositionDone av.position
 | 
				
			||||||
 | 
					
 | 
				
			||||||
finalCacheHierarchy : CacheHierarchy -> AccessView -> CacheHierarchy
 | 
					finalCacheHierarchy : AccessView -> CacheHierarchy
 | 
				
			||||||
finalCacheHierarchy ch (l, ap) =
 | 
					finalCacheHierarchy av =
 | 
				
			||||||
    List.map .output l ++ List.drop (List.length l) ch
 | 
					    List.map .output av.accessEffects ++ List.drop (List.length av.accessEffects) av.initialState
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					effectiveCacheHierarchy : AccessView -> CacheHierarchy
 | 
				
			||||||
effectiveCacheHierarchy : CacheHierarchy -> AccessView -> CacheHierarchy
 | 
					effectiveCacheHierarchy av =
 | 
				
			||||||
effectiveCacheHierarchy c (l, ap) =
 | 
					 | 
				
			||||||
    let
 | 
					    let
 | 
				
			||||||
        finalContents = List.map .output l
 | 
					        finalContents = List.map .output av.accessEffects
 | 
				
			||||||
        unaccessed = List.drop (List.length l) c
 | 
					        unaccessed = List.drop (List.length av.accessEffects) av.initialState
 | 
				
			||||||
        notDone =
 | 
					        notDone =
 | 
				
			||||||
            case ap of
 | 
					            case av.position of
 | 
				
			||||||
                Done -> []
 | 
					                Preview -> []
 | 
				
			||||||
                Down _ -> List.take (List.length l) c
 | 
					                End -> []
 | 
				
			||||||
                Up n -> List.take n c
 | 
					                Down _ -> List.take (List.length av.accessEffects) av.initialState
 | 
				
			||||||
 | 
					                Up n -> List.take n av.initialState
 | 
				
			||||||
        done =
 | 
					        done =
 | 
				
			||||||
            case ap of
 | 
					            case av.position of
 | 
				
			||||||
                Done -> finalContents
 | 
					                Preview -> finalContents
 | 
				
			||||||
 | 
					                End -> finalContents
 | 
				
			||||||
                Down _ -> []
 | 
					                Down _ -> []
 | 
				
			||||||
                Up n -> List.drop n finalContents
 | 
					                Up n -> List.drop n finalContents
 | 
				
			||||||
    in
 | 
					    in
 | 
				
			||||||
 | 
				
			|||||||
@ -45,8 +45,13 @@ updateAccess li m =
 | 
				
			|||||||
            case xs of
 | 
					            case xs of
 | 
				
			||||||
                [] -> Ok []
 | 
					                [] -> Ok []
 | 
				
			||||||
                (i::t) ->
 | 
					                (i::t) ->
 | 
				
			||||||
                    case accessCacheHierarchy i c of
 | 
					                    case accessCacheHierarchy (i // 4) c of
 | 
				
			||||||
                        Ok av -> Result.map ((::) (av, Down 0)) <| process (finalCacheHierarchy c (av, Done)) t
 | 
					                        Ok av -> 
 | 
				
			||||||
 | 
					                            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
 | 
				
			||||||
@ -59,12 +64,15 @@ 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
 | 
				
			||||||
        (newHierarchy, newAccessView) =
 | 
					        newAccessView =
 | 
				
			||||||
            case afterStep of
 | 
					            case afterStep of
 | 
				
			||||||
                Just ((avs, Done)::[]) -> (Maybe.map (\h -> finalCacheHierarchy h (avs, Done)) m.hierarchy, Nothing)
 | 
					                Just (result::xs) ->
 | 
				
			||||||
                Just ((avs, Done)::xs) -> (Maybe.map (\h -> finalCacheHierarchy h (avs, Done)) m.hierarchy, Just xs)
 | 
					                    case (result.position, xs) of
 | 
				
			||||||
                as_ -> (m.hierarchy, as_)
 | 
					                        (End, []) -> Nothing
 | 
				
			||||||
        newModel = { m | accessView = newAccessView, hierarchy = newHierarchy }
 | 
					                        (End, nxs) -> Just nxs
 | 
				
			||||||
 | 
					                        _ -> Just (result::xs)
 | 
				
			||||||
 | 
					                as_ -> as_
 | 
				
			||||||
 | 
					        newModel = { m | accessView = newAccessView }
 | 
				
			||||||
        cmd = Cmd.none
 | 
					        cmd = Cmd.none
 | 
				
			||||||
    in
 | 
					    in
 | 
				
			||||||
        (newModel, cmd)
 | 
					        (newModel, cmd)
 | 
				
			||||||
 | 
				
			|||||||
@ -10,34 +10,31 @@ 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
 | 
				
			||||||
basicButton : List (Attribute Msg) -> String -> Html Msg
 | 
					button : List (Attribute Msg) -> String -> Html Msg
 | 
				
			||||||
basicButton attrs s = input ([ type_ "button", value s, class "btn", class "btn-info" ] ++ attrs) []
 | 
					button attrs s = input ([ type_ "button", value s, class "btn"] ++ attrs) []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
disabledButton : String -> Html Msg
 | 
					basicButton : Msg -> String -> Html Msg
 | 
				
			||||||
disabledButton = basicButton [ disabled True ]
 | 
					basicButton msg s = button [ onClick msg ] s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
advancedButton : List (Attribute Msg) -> String -> Msg -> Html Msg
 | 
					disabledButton : List (Attribute Msg) -> String -> Html Msg
 | 
				
			||||||
advancedButton attrs s m = basicButton (attrs ++ [ onClick m ]) s
 | 
					disabledButton attrs = button (attrs ++ [ disabled True ])
 | 
				
			||||||
 | 
					 | 
				
			||||||
button : String -> Msg -> Html Msg
 | 
					 | 
				
			||||||
button s m = basicButton [ onClick m ] s
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
dangerButton : String -> Msg -> Html Msg
 | 
					dangerButton : String -> Msg -> Html Msg
 | 
				
			||||||
dangerButton = advancedButton [ class "btn-danger" ]
 | 
					dangerButton s m = button [ onClick m, class "btn-danger" ] s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
primaryButton : String -> Msg -> Html Msg
 | 
					primaryButton : String -> Msg -> Html Msg
 | 
				
			||||||
primaryButton = advancedButton [ class "btn-primary" ]
 | 
					primaryButton s m = button [ onClick m, class "btn-primary" ] s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
secondaryButton : String -> Msg -> Html Msg
 | 
					secondaryButton : String -> Msg -> Html Msg
 | 
				
			||||||
secondaryButton = advancedButton [ class "btn-secondary" ]
 | 
					secondaryButton s m = button [ onClick m, class "btn-secondary" ] s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
maybeButton : Maybe a -> String -> (a -> Msg) -> Html Msg
 | 
					maybeButton : Maybe a -> List (Attribute Msg) -> String -> (a -> Msg) -> Html Msg
 | 
				
			||||||
maybeButton m s f =
 | 
					maybeButton m attrs s f =
 | 
				
			||||||
    case m of
 | 
					    case m of
 | 
				
			||||||
        Just v -> button s (f v)
 | 
					        Just v -> button (attrs ++ [ onClick (f v) ]) s 
 | 
				
			||||||
        _ -> disabledButton s 
 | 
					        _ -> disabledButton attrs s 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
resultButton : Result e a -> String -> (a -> Msg) -> Html Msg
 | 
					resultButton : Result e a -> List (Attribute Msg) -> String -> (a -> Msg) -> Html Msg
 | 
				
			||||||
resultButton = maybeButton << Result.toMaybe
 | 
					resultButton = maybeButton << Result.toMaybe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- Button wrapper (button group)
 | 
					-- Button wrapper (button group)
 | 
				
			||||||
@ -105,8 +102,8 @@ viewRawCacheModelHierarchy rcmh =
 | 
				
			|||||||
                Ok _ -> viewError True ""
 | 
					                Ok _ -> viewError True ""
 | 
				
			||||||
                Err e -> viewError False e
 | 
					                Err e -> viewError False e
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        newButton = button "Add level" CreateRawModel
 | 
					        newButton = primaryButton "Add level" CreateRawModel
 | 
				
			||||||
        useButton = resultButton checkedResult "Use hierarchy" (UseHierarchy << Just) 
 | 
					        useButton = resultButton checkedResult [ class "btn-primary" ] "Start simulation" (UseHierarchy << Just) 
 | 
				
			||||||
    in
 | 
					    in
 | 
				
			||||||
        div []
 | 
					        div []
 | 
				
			||||||
            [ h2 [] [ text "Cache hierarchy" ]
 | 
					            [ h2 [] [ text "Cache hierarchy" ]
 | 
				
			||||||
@ -163,23 +160,21 @@ viewCacheHierarchy ch =
 | 
				
			|||||||
        
 | 
					        
 | 
				
			||||||
viewAccessView : Model -> AccessView -> Html Msg
 | 
					viewAccessView : Model -> AccessView -> Html Msg
 | 
				
			||||||
viewAccessView m av =
 | 
					viewAccessView m av =
 | 
				
			||||||
    let
 | 
					    div []
 | 
				
			||||||
        currentCache = Maybe.withDefault [] m.hierarchy
 | 
					        [ h2 [] [ text "Access Simulation" ]
 | 
				
			||||||
    in
 | 
					        , p [] [ text ("Simulating access of address " ++ String.fromInt av.blockAddr) ]
 | 
				
			||||||
        div []
 | 
					        , buttonWrapper
 | 
				
			||||||
            [ h2 [] [ text "Access Simulation" ]
 | 
					            [ primaryButton "Back" AccessViewBack
 | 
				
			||||||
            , buttonWrapper
 | 
					            , primaryButton "Forward" AccessViewForward
 | 
				
			||||||
                [ primaryButton "Back" AccessViewBack
 | 
					            ]
 | 
				
			||||||
                , primaryButton "Forward" AccessViewForward
 | 
					        , h3 [] [ text "Access event log" ]
 | 
				
			||||||
                ]
 | 
					        , viewAccessLog av
 | 
				
			||||||
            , h3 [] [ text "Access event log" ]
 | 
					        , h3 [] [ text "Current cache state" ]
 | 
				
			||||||
            , viewAccessLog av
 | 
					        , viewCacheHierarchy <| effectiveCacheHierarchy av
 | 
				
			||||||
            , h3 [] [ text "Current cache state" ]
 | 
					        ]   
 | 
				
			||||||
            , viewCacheHierarchy <| effectiveCacheHierarchy currentCache av
 | 
					 | 
				
			||||||
            ]   
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
viewAccessLog : AccessView -> Html Msg
 | 
					viewAccessLog : AccessView -> Html Msg
 | 
				
			||||||
viewAccessLog (aes, ap) =
 | 
					viewAccessLog av =
 | 
				
			||||||
    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) ] ]
 | 
				
			||||||
@ -189,14 +184,17 @@ viewAccessLog (aes, ap) =
 | 
				
			|||||||
            , 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 aes - n)
 | 
					            [ text <| "Updated L" ++ String.fromInt (List.length av.accessEffects - n)
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
        events = 
 | 
					        events = 
 | 
				
			||||||
            case ap of
 | 
					            case av.position of
 | 
				
			||||||
                Done -> []
 | 
					                Preview -> List.indexedMap downEvent av.accessEffects ++
 | 
				
			||||||
                Down n -> List.indexedMap downEvent <| List.take (n + 1) aes
 | 
					                    (List.indexedMap upEvent av.accessEffects) ++
 | 
				
			||||||
                Up n -> List.indexedMap downEvent aes ++
 | 
					                    [ div [ class "event" ] [ text "Access complete. Viewing final cache state." ] ]
 | 
				
			||||||
                    (List.indexedMap upEvent <| List.drop n aes)
 | 
					                End -> []
 | 
				
			||||||
 | 
					                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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -204,27 +202,26 @@ viewAccessInput : Model -> Html Msg
 | 
				
			|||||||
viewAccessInput m =
 | 
					viewAccessInput m =
 | 
				
			||||||
    let
 | 
					    let
 | 
				
			||||||
        parser =
 | 
					        parser =
 | 
				
			||||||
            Parser.map (List.map (\i -> i // 4)) <|
 | 
					            Parser.sequence
 | 
				
			||||||
                Parser.sequence
 | 
					            { start = ""
 | 
				
			||||||
                    { start = ""
 | 
					            , end = ""
 | 
				
			||||||
                    , end = ""
 | 
					            , separator = ","
 | 
				
			||||||
                    , separator = ","
 | 
					            , spaces = Parser.spaces
 | 
				
			||||||
                    , spaces = Parser.spaces
 | 
					            , item = Parser.int
 | 
				
			||||||
                    , item = Parser.int
 | 
					            , trailing = Parser.Optional
 | 
				
			||||||
                    , 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 "Access address" Access
 | 
					        accessButton = resultButton checkedResult [ class "btn-primary" ] "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 = button "Edit hierarchy" (UseHierarchy Nothing)
 | 
					        editHierarchyButton = secondaryButton "Edit hierarchy" (UseHierarchy Nothing)
 | 
				
			||||||
    in
 | 
					    in
 | 
				
			||||||
        div []
 | 
					        div []
 | 
				
			||||||
            [ h2 [] [ text "Run access simulation" ]
 | 
					            [ h2 [] [ text "Run access simulation" ]
 | 
				
			||||||
@ -244,7 +241,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 \"Use hierarchy\" to load the specified hierarchy and begin simulating. To simulate,"
 | 
					                ++ " no warnings appear, click \"Start simulation\" 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."
 | 
				
			||||||
            ]
 | 
					            ]
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user