-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Core rewrite #21
base: main
Are you sure you want to change the base?
Core rewrite #21
Changes from 11 commits
3a3bcf1
5ae3549
03490a2
f22318b
142fb67
076670f
e8c6d4e
396c345
f20525b
47cdb69
c42efc4
957dd8b
69b3439
77a1365
beb03b7
cb4f812
9204022
28948dc
fcc12c1
ee84822
dfd0921
503c9a1
6c44b6a
8c684c2
f1d32ac
833d147
9e0c858
98f2046
d4f2574
6db019e
27f82a3
52030f6
1918777
fa9b564
4afd346
fa5f3be
ed75dd2
c8d17af
2564570
9fce015
3547c90
3893e18
3262a04
7ee225d
be705c9
164643d
43c3e6f
01db43e
9e46b32
b685955
2ca782d
1240556
63aa4ef
462d8d5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,10 +21,10 @@ import INet.Net | |
Node 2 -> | ||
ReduceRuleResult 2 2 2 | ||
lNode |><| rNode = case (lNode ^. nodeType, rNode ^. nodeType) of | ||
(Apply, Abs) -> applyToLambdaRule lNode rNode | ||
(Abs, Apply) -> applyToLambdaRule lNode rNode | ||
(Eps, _) -> epsToAnyRule lNode rNode | ||
(_, Eps) -> epsToAnyRule rNode lNode | ||
(Apply, Abstract) -> applyToLambdaRule lNode rNode | ||
(Abstract, Apply) -> applyToLambdaRule lNode rNode | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be left and right node be switched? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is symmetrical |
||
(Erase, _) -> epsToAnyRule lNode rNode | ||
(_, Erase) -> epsToAnyRule rNode lNode | ||
_ -> error "There is no rule for this active pair in the reduction rules" | ||
|
||
{- | Reduce rule for `Apply` and `Abs` | ||
|
@@ -60,7 +60,7 @@ epsToAnyRule :: | |
ReduceRuleResult portsNumber edgesNumber portsNumber | ||
epsToAnyRule _ nSome = | ||
let arisingEdges = def | ||
genNewEpsNode port = Node port def Eps | ||
genNewEpsNode port = Node port def Erase | ||
arisingNodes = | ||
imap | ||
(\i maybePort -> flip LocalNode (indexToUnsigned i) . genNewEpsNode <$> maybePort) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} | ||
{-# HLINT ignore "Eta reduce" #-} | ||
{-# OPTIONS_GHC -Wno-unused-local-binds #-} | ||
|
||
module Core.Core where | ||
|
||
import Clash.Prelude | ||
import Control.Lens hiding ((:>)) | ||
import Core.Loader (Ram, loadActivePair, loadInterface) | ||
import Core.MemoryManager.ChangesAccumulator (getAllChangesByDelta) | ||
import Core.MemoryManager.MemoryManager ( | ||
ActivePair, | ||
MemoryManager, | ||
giveActiveAddressNumber, | ||
leftNode, | ||
removeActivePair, | ||
rightNode, | ||
) | ||
import Core.MemoryManager.NodeChanges | ||
import Core.Node | ||
import Core.Reducer (ChooseReductionRule, getInterface, reducer) | ||
|
||
core :: | ||
forall portsNumber nodesNumber edgesNumber cellsNumber dom. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can core be parametrized with single |
||
( KnownNat portsNumber | ||
, KnownNat nodesNumber | ||
, KnownNat edgesNumber | ||
, KnownNat cellsNumber | ||
, 1 <= cellsNumber | ||
, CLog 2 cellsNumber <= BitSize AddressNumber | ||
, nodesNumber <= cellsNumber | ||
, KnownDomain dom | ||
, HiddenClockResetEnable dom | ||
, Enum AddressNumber | ||
) => | ||
Vec cellsNumber (Maybe (Node portsNumber)) -> -- Initial network | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not a network, but active pairs. We need (at least) two layers: program loader and processor itself. |
||
MemoryManager cellsNumber -> -- Initial information about busy addresses and active pairs | ||
ChooseReductionRule cellsNumber nodesNumber edgesNumber portsNumber -> | ||
Signal dom (Vec cellsNumber (Maybe (Node portsNumber))) | ||
core initialNetwork initialMemoryManager chooseReductionRule = bundle $ map (`ram` def) (unbundle allAddresses) | ||
where | ||
memoryManager = register @dom initialMemoryManager allocatedAddressesMemoryManager | ||
ram = blockRam initialNetwork :: Ram dom portsNumber | ||
activeAddress = case sequenceA $ giveActiveAddressNumber memoryManager of | ||
Just x -> x | ||
Nothing -> error "" -- end of program. TODO: add handling of this | ||
acPair = loadActivePair ram activeAddress | ||
removedActivePairMemoryManager = removeActivePair acPair memoryManager | ||
_ = removeActivePairFromRam ram acPair | ||
(delta, allocatedAddressesMemoryManager) = reducer chooseReductionRule removedActivePairMemoryManager acPair | ||
-- instead of "@portsNumber @nodesNumber" it possible to write ":: Signal dom (Interface nodesNumber)" | ||
interface = getInterface @portsNumber @nodesNumber <$> acPair | ||
externalNodes = loadInterface ram interface | ||
changes = updateLoadedNodesByChanges <$> externalNodes <*> getAllChangesByDelta delta interface | ||
_ = writeChanges ram changes | ||
allAddresses = pure (generateI (+ 1) (0 :: AddressNumber)) | ||
|
||
writeChanges :: | ||
(KnownNat maxNumOfChangedNodes, KnownNat portsNumber, KnownDomain dom, HiddenClockResetEnable dom) => | ||
Ram dom portsNumber -> | ||
Signal dom (Vec maxNumOfChangedNodes (Maybe (LoadedNode portsNumber))) -> | ||
Vec maxNumOfChangedNodes (Signal dom (Maybe (Node portsNumber))) | ||
writeChanges ram changes = map writeByLoadedNode (unbundle changes) | ||
where | ||
writeByLoadedNode signalMaybeLoadedNode = case sequenceA signalMaybeLoadedNode of | ||
Nothing -> ram (pure 0) def | ||
Just signalLoadedNode -> | ||
let f = Just (view originalAddress <$> signalLoadedNode, Just . view containedNode <$> signalLoadedNode) | ||
in ram (pure 0) (traverse bundle f) | ||
|
||
removeActivePairFromRam :: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should it be here, not in Ram module? |
||
Ram dom portsNumber -> Signal dom (ActivePair portsNumber) -> Vec 2 (Signal dom (Maybe (Node portsNumber))) | ||
removeActivePairFromRam ram acPair = map (\address -> partRam (Just <$> bundle (address, def))) (leftAddress :> rightAddress :> Nil) | ||
where | ||
partRam = ram def | ||
leftAddress = view (leftNode . originalAddress) <$> acPair | ||
rightAddress = view (rightNode . originalAddress) <$> acPair |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,57 @@ | ||
module Core.Loader where | ||
|
||
import Clash.Prelude | ||
import Control.Lens (view) | ||
import Core.MemoryManager.MemoryManager (ActivePair (ActivePair)) | ||
import Core.MemoryManager.NodeChanges | ||
import Core.Node | ||
|
||
-- | Get `Node` by his `AddressNumber` from RAM. Actually, preparing to reducer work. | ||
loader :: | ||
-- | Type alias for partial applied `blockRam` | ||
type Ram dom portsNumber = | ||
( Signal dom AddressNumber -> | ||
Signal dom (Maybe (AddressNumber, Maybe (Node portsNumber))) -> | ||
Signal dom (Maybe (Node portsNumber)) | ||
) | ||
|
||
-- | Read external `Node`s from ram | ||
loadInterface :: | ||
( KnownDomain dom | ||
, HiddenClockResetEnable dom | ||
, KnownNat numberOfPorts | ||
, KnownNat portsNumber | ||
, KnownNat externalNodesNumber | ||
) => | ||
(Signal dom AddressNumber -> Signal dom (Node numberOfPorts)) -> | ||
Signal dom (Maybe AddressNumber) -> | ||
Signal dom (Maybe (LoadedNode numberOfPorts)) | ||
loader ram mbAddressNumberToLoad = | ||
mkLoadedNode <$> mbNode <*> mbAddressNumberToLoad | ||
Ram dom portsNumber -> | ||
Signal dom (Interface externalNodesNumber) -> | ||
Signal dom (Vec externalNodesNumber (Maybe (LoadedNode portsNumber))) | ||
loadInterface ram interface = | ||
bundle $ | ||
map | ||
(traverse readFromRam . sequenceA) | ||
(unbundle interface) | ||
where | ||
partRam address = ram address def | ||
readFromRam address = case sequenceA (partRam address) of | ||
Just node -> LoadedNode <$> node <*> address | ||
Nothing -> error "An attempt to read at a free address" | ||
|
||
-- | Load `ActivePair` by `AddressNumber`. It is assumed that `AddressNumber` is actually active | ||
loadActivePair :: | ||
(KnownDomain dom, HiddenClockResetEnable dom, KnownNat portsNumber) => | ||
Ram dom portsNumber -> | ||
Signal dom AddressNumber -> | ||
Signal dom (ActivePair portsNumber) | ||
loadActivePair ram leftActiveNodeAddress = | ||
ActivePair | ||
<$> (LoadedNode <$> leftActiveNode <*> leftActiveNodeAddress) | ||
<*> (LoadedNode <$> rightActiveNode <*> rightActiveNodeAddress) | ||
where | ||
mkLoadedNode node address = LoadedNode <$> node <*> address | ||
mbNode = case sequenceA mbAddressNumberToLoad of | ||
Nothing -> pure Nothing | ||
Just n -> sequenceA $ Just (ram n) | ||
partRam address = ram address def | ||
getNodeByAddress address = case sequenceA $ partRam address of | ||
Just node -> node | ||
Nothing -> error "An attempt to read at a free address" | ||
getRightActiveNodeAddress node = case view primaryPort node of | ||
Connected port -> view nodeAddress port | ||
NotConnected -> error "Wrong definition of active pair" | ||
leftActiveNode = getNodeByAddress leftActiveNodeAddress | ||
rightActiveNodeAddress = getRightActiveNodeAddress <$> leftActiveNode | ||
rightActiveNode = getNodeByAddress rightActiveNodeAddress |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is
Core' a good name for top-level ? May we use something like
ReductionMachine` for top-level namespace?