mirror of
https://github.com/supleed2/ELEC60015-HLP-CW.git
synced 2024-12-22 13:35:50 +00:00
Working ap1919 gv319 Symbol code.
This commit is contained in:
parent
c6e5381f61
commit
51b5cbdb32
|
@ -1,4 +1,9 @@
|
|||
(*
|
||||
//---------------------------------------------------------------------------------//
|
||||
//--------------------AP1919 CODE SECTION STARTS-------------------------------------//
|
||||
//---------------------------------------------------------------------------------//
|
||||
|
||||
|
||||
(*
|
||||
This module draws schematics component symbols. Each symbol is associated with a unique Issie component.
|
||||
*)
|
||||
|
||||
|
@ -13,9 +18,11 @@ open CommonTypes
|
|||
open System.Text.RegularExpressions
|
||||
|
||||
|
||||
/// --------- STATIC VARIABLES --------- ///
|
||||
|
||||
/// --------- STATIC VARIABLES --------- ///
|
||||
let GridSize = 30
|
||||
|
||||
// let (x:ComponentType List) = [MergeWires ;(SplitWire,a);Mux2 ;NbitsAdder x; IOLabel]
|
||||
/// ---------- SYMBOL TYPES ---------- ///
|
||||
type Rotation = R0 | R90 | R180 | R270
|
||||
|
||||
|
@ -91,8 +98,6 @@ let posAdd (a:XYPos) (b:XYPos) =
|
|||
|
||||
let posOf x y = {X=x;Y=y}
|
||||
|
||||
|
||||
// ----- helper functions for titles ----- //
|
||||
//STransform Finite State Machine
|
||||
let stransform_fsm(prev_state:Rotation):Rotation =
|
||||
match prev_state with
|
||||
|
@ -101,16 +106,16 @@ let stransform_fsm(prev_state:Rotation):Rotation =
|
|||
| R180 -> R270
|
||||
| R270 -> R0
|
||||
|
||||
///Insert titles compatible with greater than 1 bus width
|
||||
let title t n =
|
||||
if n = 1 then t else t + "(" + string(n-1) + "..0)"
|
||||
// ----- helper functions for titles ----- //
|
||||
|
||||
///Insert titles for bus select
|
||||
let bustitle wob lsb =
|
||||
let titleGen text (buswidth) =
|
||||
if buswidth = 1 then text else text + "(" + string(buswidth-1) + "..0)"
|
||||
|
||||
let bustitleGen wob lsb =
|
||||
if wob <> 1 then"(" + string(wob + lsb - 1) + ".." + string(lsb) + ")" else string(lsb)
|
||||
|
||||
///Decodes the component type into component labels
|
||||
let prefix compType =
|
||||
let getLabel compType =
|
||||
match compType with
|
||||
| Not | And | Or | Xor | Nand | Nor | Xnor -> "G"
|
||||
| Mux2 -> "MUX"
|
||||
|
@ -135,28 +140,28 @@ let prefix compType =
|
|||
//-----------------------------Skeleton Model Type for symbols----------------//
|
||||
|
||||
// Text to be put inside different Symbols depending on their ComponentType
|
||||
let gateDecoderType (comp:Component) =
|
||||
let getTitle (comp:Component) =
|
||||
match comp.Type with
|
||||
| And | Nand-> "&"
|
||||
| Or | Nor-> "≥1"
|
||||
| Xor | Xnor -> "=1"
|
||||
| Not -> "1"
|
||||
| Decode4 -> "Decode"
|
||||
| NbitsAdder n -> title "Adder" n
|
||||
| Register n | RegisterE n-> title "Register" n
|
||||
| NbitsAdder n -> titleGen "Adder" n
|
||||
| Register n | RegisterE n-> titleGen "Register" n
|
||||
| AsyncROM1 _ -> "Async-ROM"
|
||||
| ROM1 _ -> "Sync-ROM"
|
||||
| RAM1 _ -> "Sync-RAM"
|
||||
| AsyncRAM1 _ -> "Async-RAM"
|
||||
| DFF -> "DFF"
|
||||
| DFFE -> "DFFE"
|
||||
| NbitsXor x-> title "N-bits-Xor" x
|
||||
| NbitsXor (x)-> titleGen "N-bits-Xor" x
|
||||
| Custom x -> x.Name
|
||||
| _ -> ""
|
||||
|
||||
|
||||
let createCustomPortNamesMap inputLabels outputLabels =
|
||||
let adder x (name:string,_) (portType:PortType) =
|
||||
///Helper function to create portNamesMap for custom components
|
||||
let customPortNamesMap inputLabels outputLabels =
|
||||
let adder x ((name:string),n) (portType:PortType)=
|
||||
let key =
|
||||
match portType with
|
||||
|PortType.Input -> "I"+ string x
|
||||
|
@ -167,9 +172,9 @@ let createCustomPortNamesMap inputLabels outputLabels =
|
|||
|
||||
[inputList;outputList] |> List.concat |> Map.ofList
|
||||
|
||||
// Input and Output names of the ports depending on their ComponentType
|
||||
// returns map with (port key in APortOffsetsMap, port name)
|
||||
let portNameMap (comp:Component) =
|
||||
/// Input and Output names of the ports depending on their ComponentType
|
||||
/// returns map with (port key in APortOffsetsMap, port name)
|
||||
let portNamesMap (comp:Component) =
|
||||
match comp.Type with
|
||||
| NbitsAdder _ -> Map [ ("I0", "Cin"); ("I1", "A"); ("I2","B");("O0","Sum");("O1","Cout") ]
|
||||
| Decode4 -> Map [ ("I0", "Sel"); ("I1", "Data"); ("O0","0");("O1","1"); ("O2","2");("O3","3") ]
|
||||
|
@ -181,7 +186,7 @@ let portNameMap (comp:Component) =
|
|||
| Mux2 -> Map [ ("I0", "0"); ("I1", "1"); ("I2","SEL");("O0","OUT") ]
|
||||
| Demux2 -> Map [ ("I0", "IN"); ("I1", "SEL"); ("O0","0");("O1","1") ]
|
||||
| NbitsXor _ -> Map [ ("I0", "P"); ("I1", "Q"); ("O0","Out") ]
|
||||
| Custom x -> createCustomPortNamesMap x.InputLabels x.OutputLabels
|
||||
| Custom x -> customPortNamesMap x.InputLabels x.OutputLabels
|
||||
|_ -> Map.empty
|
||||
// |Mux4 -> (["0"; "1"; "2"; "3" ;"SEL"],["OUT"])
|
||||
// |Demux4 -> (["IN"; "SEL"],["0"; "1";"2"; "3";])
|
||||
|
@ -189,9 +194,24 @@ let portNameMap (comp:Component) =
|
|||
// |Mux8 -> (["0"; "1"; "2" ; "3" ; "4" ; "5" ; "6" ; "7";"SEL"],["OUT"])
|
||||
// |_ -> ([],[])
|
||||
// EXTENSION: Extra Components made that are not currently in Issie. Can be extended later by using this code as it is .
|
||||
// !! They need to be in Map Format !!
|
||||
|
||||
/// Genererates a list of ports:
|
||||
let portLists numOfPorts hostID portType =
|
||||
|
||||
|
||||
//-----------------------Component and Symbol Creation---------------------//
|
||||
|
||||
///Rounds an integer to any given number. The first parameter is the number to round to, the second parameter is the input number that will be rounded
|
||||
let inline roundToZ (z : int) (number : int) = //IMPLEMENT IT INSIDE ARGS??? -> DETELE IT???
|
||||
number + abs((number % z) - z)
|
||||
|
||||
//Find the custom component's I/O label with the maximum size
|
||||
let customCompMaxLabel (lst : (string * int) list) =
|
||||
let labelList = List.map (fst >> String.length) lst
|
||||
if List.isEmpty labelList then 0 //if a component has no inputs or outputs list max will fail
|
||||
else List.max labelList
|
||||
|
||||
/// Genererates a component's Input/Output Port list
|
||||
let portListGen numOfPorts hostID portType =
|
||||
if numOfPorts < 1
|
||||
then []
|
||||
else
|
||||
|
@ -204,82 +224,72 @@ let portLists numOfPorts hostID portType =
|
|||
HostId = hostID
|
||||
}])
|
||||
|
||||
|
||||
//-----------------------Skeleton Message type for symbols---------------------//
|
||||
|
||||
///Rounds an integer to any given number. The first parameter is the number to round to, the second parameter is the input number that will be rounded
|
||||
let roundToN (n : int) (x : int) =
|
||||
x + abs((x % n) - n)
|
||||
|
||||
let customToLength (lst : (string * int) list) =
|
||||
let labelList = List.map (fst >> String.length) lst
|
||||
if List.isEmpty labelList then 0 //if a component has no inputs or outputs list max will fail
|
||||
else List.max labelList
|
||||
|
||||
// helper function to initialise each type of component
|
||||
let makeComp (pos: XYPos) (comptype: ComponentType) (id:string) (label:string) : Component =
|
||||
|
||||
// function that helps avoid dublicate code by initialising parameters that are the same for all component types and takes as argument the others
|
||||
let makeComponent (n, nout, h, w) label : Component=
|
||||
{
|
||||
Id = id
|
||||
Type = comptype
|
||||
Label = label
|
||||
InputPorts = portLists n id PortType.Input
|
||||
OutputPorts = portLists nout id PortType.Output
|
||||
X = int (pos.X - float w / 2.0)
|
||||
Y = int (pos.Y - float h / 2.0)
|
||||
H = h
|
||||
W = w
|
||||
}
|
||||
/// Helper function to initialise each type of component
|
||||
let createComponent (pos: XYPos) (comptype: ComponentType) (id:string) (label:string) : Component =
|
||||
|
||||
// match statement for each component type. the output is a 4-tuple that is used as an input to makecomponent (see below)
|
||||
// 4-tuple of the form ( number of input ports, number of output ports, Height, Width)
|
||||
let args =
|
||||
//grid size is set at the begining
|
||||
let characteristics =
|
||||
match comptype with
|
||||
| ROM _ | RAM _ | AsyncROM _ ->
|
||||
failwithf "What? Legacy RAM component types should never occur"
|
||||
| And | Nand | Or | Nor | Xnor | Xor -> (2 , 1, 2*GridSize , 2*GridSize)
|
||||
| Not -> ( 1 , 1, 2*GridSize , 2*GridSize)
|
||||
| ComponentType.Input _ -> ( 0 , 1, GridSize , 2*GridSize)
|
||||
| ComponentType.Output _ -> ( 1 , 0, GridSize , 2*GridSize)
|
||||
| ComponentType.Viewer _ -> ( 1 , 0, GridSize , GridSize)
|
||||
| ComponentType.Input (a) -> ( 0 , 1, GridSize , 2*GridSize)
|
||||
| ComponentType.Output (a) -> ( 1 , 0, GridSize , 2*GridSize)
|
||||
| ComponentType.Viewer a -> ( 1 , 0, GridSize , GridSize)
|
||||
| ComponentType.IOLabel ->( 1 , 1, GridSize , 2*GridSize)
|
||||
| Decode4 ->( 2 , 4 , 4*GridSize , 3*GridSize)
|
||||
| Constant1 _ | Constant _ -> ( 0 , 1, GridSize , 2*GridSize)
|
||||
| Constant1 (a, b,_) | Constant(a, b) -> ( 0 , 1, GridSize , 2*GridSize)
|
||||
| MergeWires -> ( 2 , 1, 2*GridSize , 2*GridSize)
|
||||
| SplitWire _ ->( 1 , 2 , 2*GridSize , 2*GridSize)
|
||||
| SplitWire (a) ->( 1 , 2 , 2*GridSize , 2*GridSize)
|
||||
| Mux2 -> ( 3 , 1, 3*GridSize , 2*GridSize)
|
||||
// EXTENSION: | Mux4 -> ( 5 , 1, 5*GridSize , 2*GridSize)
|
||||
// EXTENSION: | Mux8 -> ( 9 , 1, 7*GridSize , 2*GridSize)
|
||||
| Demux2 ->( 2 , 2, 3*GridSize , 2*GridSize)
|
||||
// EXTENSION: | Demux4 -> ( 2 , 4, 150 , 50)
|
||||
// EXTENSION: | Demux8 -> ( 2 , 8, 200 , 50)
|
||||
| BusSelection _ -> ( 1 , 1, GridSize, 2*GridSize)
|
||||
| BusCompare _ -> ( 1 , 1, GridSize , 2*GridSize)
|
||||
| BusSelection (a, b) -> ( 1 , 1, GridSize, 2*GridSize)
|
||||
| BusCompare (a, b) -> ( 1 , 1, GridSize , 2*GridSize)
|
||||
| DFF -> ( 1 , 1, 3*GridSize , 3*GridSize)
|
||||
| DFFE -> ( 2 , 1, 3*GridSize , 3*GridSize)
|
||||
| Register _ -> ( 1 , 1, 3*GridSize , 4*GridSize )
|
||||
| RegisterE _ -> ( 2 , 1, 3*GridSize , 4*GridSize)
|
||||
| AsyncROM1 _ -> ( 1 , 1, 3*GridSize , 4*GridSize)
|
||||
| ROM1 _ -> ( 1 , 1, 3*GridSize , 4*GridSize)
|
||||
| RAM1 _ | AsyncRAM1 _ -> ( 3 , 1, 3*GridSize , 4*GridSize)
|
||||
| NbitsXor _ -> ( 2 , 1, 3*GridSize , 4*GridSize)
|
||||
| NbitsAdder _ -> ( 3 , 2, 3*GridSize , 4*GridSize)
|
||||
| Register (a) -> ( 1 , 1, 3*GridSize , 4*GridSize )
|
||||
| RegisterE (a) -> ( 2 , 1, 3*GridSize , 4*GridSize)
|
||||
| AsyncROM1 (a) -> ( 1 , 1, 3*GridSize , 4*GridSize)
|
||||
| ROM1 (a) -> ( 1 , 1, 3*GridSize , 4*GridSize)
|
||||
| RAM1 (a) | AsyncRAM1 a -> ( 3 , 1, 3*GridSize , 4*GridSize)
|
||||
| NbitsXor (n) -> ( 2 , 1, 3*GridSize , 4*GridSize)
|
||||
| NbitsAdder (n) -> ( 3 , 2, 3*GridSize , 4*GridSize)
|
||||
| Custom x ->
|
||||
let h = GridSize + GridSize * (List.max [List.length x.InputLabels; List.length x.OutputLabels])
|
||||
let maxInLength, maxOutLength = customToLength x.InputLabels, customToLength x.OutputLabels
|
||||
let maxInLength, maxOutLength = customCompMaxLabel x.InputLabels, customCompMaxLabel x.OutputLabels
|
||||
let maxW = maxInLength + maxOutLength + label.Length
|
||||
let scaledW = roundToN GridSize (maxW * GridSize / 5) //Divide by 5 is just abitrary as otherwise the symbols would be too wide
|
||||
let scaledW = roundToZ GridSize (maxW * GridSize / 5) //Divide by 5 is just abitrary as otherwise the symbols would be too wide
|
||||
let w = max scaledW (GridSize * 4) //Ensures a minimum width if the labels are very small
|
||||
( List.length x.InputLabels, List.length x.OutputLabels, h , w)
|
||||
|
||||
makeComponent args label
|
||||
|
||||
|
||||
// function that helps avoid dublicate code by initialising parameters that are the same for all component types and takes as argument the others
|
||||
let createComponent' (inputPortsNo, outputPortsNo, h, w) label : Component=
|
||||
{
|
||||
Id = id
|
||||
Type = comptype
|
||||
Label = label
|
||||
InputPorts = portListGen inputPortsNo id PortType.Input
|
||||
OutputPorts = portListGen outputPortsNo id PortType.Output
|
||||
X = int (pos.X - float w / 2.0)
|
||||
Y = int (pos.Y - float h / 2.0)
|
||||
H = h
|
||||
W = w
|
||||
}
|
||||
|
||||
createComponent' characteristics label
|
||||
|
||||
// Function to generate a new symbol
|
||||
/// Function to generate a new symbol
|
||||
let createNewSymbol (pos: XYPos) (comptype: ComponentType) (label:string) =
|
||||
let id = JSHelpers.uuid ()
|
||||
let comp = makeComp pos comptype id label
|
||||
let comp = createComponent pos comptype id label
|
||||
{
|
||||
Pos = { X = pos.X - float comp.W / 2.0; Y = pos.Y - float comp.H / 2.0 }
|
||||
STransform = R0;
|
||||
|
@ -292,19 +302,21 @@ let createNewSymbol (pos: XYPos) (comptype: ComponentType) (label:string) =
|
|||
Compo = comp
|
||||
Opacity = 1.0
|
||||
Moving = false
|
||||
APortOffsetsMap = Map.empty<string,PortOrientationOffset>
|
||||
}
|
||||
APortOffsetsMap = Map.empty<string,PortOrientationOffset> //this is initialised as empty and then the map is added in the addsymbol function (line: )
|
||||
} //for readme: this is because the component is not a parameter of the createNewSymbol function
|
||||
//and adding it requires many changes in the other section of symbol. Ofcourse it is better to have it here so maybe a TODO during group work
|
||||
|
||||
// Function to add ports to port model
|
||||
let addToPortModel (model: Model) (sym: Symbol) =
|
||||
/// Function to add ports to port model
|
||||
let addPortsToModel (model: Model) (symbol: Symbol) =
|
||||
let addOnePort (currentPorts: Map<string, Port>) (port: Port) =
|
||||
Map.add port.Id port currentPorts
|
||||
|
||||
let addedInputPorts = (model.Ports, sym.Compo.InputPorts) ||> List.fold addOnePort
|
||||
(addedInputPorts, sym.Compo.OutputPorts) ||> List.fold addOnePort
|
||||
let addedInputPorts = (model.Ports, symbol.Compo.InputPorts) ||> List.fold addOnePort
|
||||
(addedInputPorts, symbol.Compo.OutputPorts) ||> List.fold addOnePort
|
||||
|
||||
|
||||
//////////////////////KEEP ONLY SO THAT THE CODE COMPILES -> IT AFFECTS GV319'S CODE ///////////////////////////////////
|
||||
|
||||
//////////////////////KEEP ONLY SO THAT THE CODE COMPILES -> IT AFFECTS 2nd part of symbol (lines: 750 - END) ///////////////////////////////////
|
||||
//-----------------------------------------GET PORT POSITION---------------------------------------------------
|
||||
// Function that calculates the positions of the ports
|
||||
|
||||
|
@ -315,8 +327,8 @@ let inline getPortPosEdgeGap (ct: ComponentType) =
|
|||
| _ -> 1.0
|
||||
|
||||
let getPortPos (comp: Component) (port:Port) =
|
||||
let ports, posX =
|
||||
if port.PortType = PortType.Input then
|
||||
let (ports, posX) =
|
||||
if port.PortType = (PortType.Input) then
|
||||
(comp.InputPorts, 0.0)
|
||||
else
|
||||
(comp.OutputPorts, float( comp.W ))
|
||||
|
@ -327,22 +339,15 @@ let getPortPos (comp: Component) (port:Port) =
|
|||
let getPortPosModel (model: Model) (port:Port) =
|
||||
getPortPos (Map.find (ComponentId port.HostId) model.Symbols).Compo port
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------DRAWING HELPERS ---------------------------------------------------
|
||||
// Text adding function with many parameters (such as bold, position and text)
|
||||
let private addText posX posY name txtPos weight size=
|
||||
let text =
|
||||
{defaultText with TextAnchor = txtPos; FontWeight = weight; FontSize = size}
|
||||
[makeText posX posY name text]
|
||||
|
||||
|
||||
/////// APORTOFFSET MAP HELPERS //////
|
||||
//---------------------------------------APortOffsetMap HELPERS ----------------------------------------------//
|
||||
///Helper function to find XYPos of ports on the RHS/LHS
|
||||
let offsethelper (comp: Component) orientation (port:Port) =
|
||||
let inline getPortPosEdgeGap (ct: ComponentType) =
|
||||
match ct with
|
||||
| MergeWires | SplitWire _ -> 0.25
|
||||
| _ -> 1.0
|
||||
let ports, posX =
|
||||
if port.PortType = PortType.Input then
|
||||
let (ports, posX) =
|
||||
if port.PortType = (PortType.Input) then
|
||||
(comp.InputPorts, 0.0)
|
||||
else
|
||||
(comp.OutputPorts, float( comp.W ))
|
||||
|
@ -351,10 +356,10 @@ let offsethelper (comp: Component) orientation (port:Port) =
|
|||
let posY = (float(comp.H))* (( index + gap )/( float( ports.Length ) + 2.0*gap - 1.0)) // the ports are created so that they are equidistant
|
||||
{X=posX;Y=posY}
|
||||
|
||||
/////change name
|
||||
/// Helper function which creates the keys and values of the APortOffsetMap from the Input/Output Port list of component
|
||||
let portListToMap (portList: Port List) (symbol: Symbol) : Map<string,PortOrientationOffset>=
|
||||
let adder (symbol: Symbol) (port: Port) =
|
||||
let num = match port.PortNumber with |Some n -> n |_-> -1
|
||||
let num = match port.PortNumber with |Some n -> n |_->(-1)
|
||||
let key =
|
||||
match port.PortType with
|
||||
|PortType.Input -> "I"+ string num
|
||||
|
@ -367,20 +372,20 @@ let portListToMap (portList: Port List) (symbol: Symbol) : Map<string,PortOrient
|
|||
if (portList.Length) < 1 then [] |> Map.ofList
|
||||
else ( [0..(portList.Length-1)] |> List.collect (fun x -> (adder symbol portList[x])) ) |> Map.ofList
|
||||
|
||||
|
||||
/// APortOffsetsMap generator
|
||||
let genAPortOffsets (symbol: Symbol) (cType: ComponentType) : Map<string,PortOrientationOffset> =
|
||||
|
||||
//generator for MUX
|
||||
let genAPortOffsetsMux (symbol: Symbol) =
|
||||
let getPosY index = (float(symbol.Compo.H))* (( index + 1.0 )/(3.0))
|
||||
let temp = [ ("I0", {Side=Left;Offset={X=0.0;Y=(getPosY 0.0)}});("I1", {Side=Left;Offset={X=0.0;Y=(getPosY 1.0)}});("I2", {Side=Left;Offset={X=float(symbol.Compo.W)/2.0;Y=float(symbol.Compo.H)*0.9}});("O0", {Side=Right;Offset={X=float(symbol.Compo.W);Y=float(symbol.Compo.H)/2.0}})]
|
||||
temp |> Map.ofList
|
||||
|
||||
Map.ofList [ ("I0", {Side=Left;Offset={X=0.0;Y=(getPosY 0.0)}});("I1", {Side=Left;Offset={X=0.0;Y=(getPosY 1.0)}});("I2", {Side=Bottom;Offset={X=float(symbol.Compo.W)/2.0;Y=float(symbol.Compo.H)*0.9}});("O0", {Side=Right;Offset={X=float(symbol.Compo.W);Y=float(symbol.Compo.H)/2.0}})]
|
||||
|
||||
|
||||
//generator for NBitsAdder
|
||||
let genAPortOffsetsAdder (symbol: Symbol) =
|
||||
let getPosY index = (float(symbol.Compo.H))* (( index + 1.0 )/(3.0))
|
||||
let temp = [ ("I2", {Side=Left;Offset={X=0.0;Y=(getPosY 1.0)}});("I1", {Side=Left;Offset={X=0.0;Y=(getPosY 0.0)}});("I0", {Side=Bottom;Offset={X=float(symbol.Compo.W)/2.0;Y=float(symbol.Compo.H)}});("O0", {Side=Right;Offset={X=float(symbol.Compo.W);Y=float(symbol.Compo.H)/3.0}});("O1", {Side=Top;Offset={X=float(symbol.Compo.W)-30.0;Y=0.0}})]
|
||||
temp |> Map.ofList
|
||||
|
||||
Map.ofList [ ("I0", {Side=Bottom;Offset={X=float(symbol.Compo.W)/3.0;Y=float(symbol.Compo.H)}});("I1", {Side=Left;Offset={X=0.0;Y=(getPosY 0.0)}}); ("I2", {Side=Left;Offset={X=0.0;Y=(getPosY 1.0)}}); ("O0", {Side=Right;Offset={X=float(symbol.Compo.W);Y=float(symbol.Compo.H)/3.0}});("O1", {Side=Top;Offset={X=float(symbol.Compo.W)-30.0;Y=0.0}})]
|
||||
|
||||
//generator for everything else
|
||||
let genAPortOffsets' (symbol: Symbol) : Map<string,PortOrientationOffset> =
|
||||
let inputList = symbol.Compo.InputPorts
|
||||
|
@ -393,10 +398,24 @@ let genAPortOffsets (symbol: Symbol) (cType: ComponentType) : Map<string,PortOri
|
|||
|Mux2 -> genAPortOffsetsMux symbol
|
||||
|NbitsAdder _ -> genAPortOffsetsAdder symbol
|
||||
|_ -> genAPortOffsets' symbol
|
||||
|
||||
|
||||
|
||||
|
||||
/// Rotates port posistion (given the symbol rotation) by updating the APortOffsetsMap
|
||||
let rotatePortMap (map:Map<string,PortOrientationOffset>) (symbol:Symbol) =
|
||||
|
||||
let rotatePortMapMux (map:Map<string,PortOrientationOffset>) (symbol:Symbol) =
|
||||
match symbol.STransform with
|
||||
|R0 -> Map.ofList [ ("I0", {Side=Top;Offset={X=(float(symbol.Compo.H)*2.0/3.0);Y=(0.0)}});("I1", {Side=Top;Offset={X=(float(symbol.Compo.H)/3.0);Y=(0.0)}});("I2", {Side=Left;Offset={X=float(symbol.Compo.H)*0.1;Y=float(symbol.Compo.W)/2.0}});("O0", {Side=Bottom;Offset={X=float(symbol.Compo.H)/2.0;Y=float(symbol.Compo.W)}})]
|
||||
|R90 -> Map.ofList [ ("I0", {Side=Right;Offset={X=float(symbol.Compo.W);Y=(float(symbol.Compo.H)*2.0/3.0)}});("I1", {Side=Right;Offset={X=float(symbol.Compo.W);Y=(float(symbol.Compo.H)/3.0)}});("I2", {Side=Top;Offset={X=float(symbol.Compo.W)/2.0;Y=float(symbol.Compo.H)*0.1}});("O0", {Side=Left;Offset={X=0.0;Y=float(symbol.Compo.H)/2.0}})]
|
||||
|R180 -> Map.ofList [ ("I0", {Side=Bottom;Offset={X=(float(symbol.Compo.H)/3.0);Y=float(symbol.Compo.W)}});("I1", {Side=Bottom;Offset={X=(float(symbol.Compo.H)*2.0/3.0);Y=float(symbol.Compo.W)}});("I2", {Side=Right;Offset={X=float(symbol.Compo.H)*0.9;Y=float(symbol.Compo.W)/2.0}});("O0", {Side=Top;Offset={X=float(symbol.Compo.H)/2.0;Y=0.0}})]
|
||||
|R270 -> Map.ofList [ ("I0", {Side=Left;Offset={X=0.0;Y=(float(symbol.Compo.H)/3.0)}});("I1", {Side=Left;Offset={X=0.0;Y=(float(symbol.Compo.H)*2.0/3.0)}});("I2", {Side=Bottom;Offset={X=float(symbol.Compo.W)/2.0;Y=float(symbol.Compo.H)*0.9}});("O0", {Side=Right;Offset={X=float(symbol.Compo.W);Y=float(symbol.Compo.H)/2.0}})]
|
||||
|
||||
let rotatePortMapAdder (map:Map<string,PortOrientationOffset>) (symbol:Symbol) =
|
||||
match symbol.STransform with
|
||||
|R0 -> Map.ofList [ ("I0", {Side=Left;Offset={X=0.0;Y=float(symbol.Compo.W)/3.0}});("I1", {Side=Top;Offset={X=float(symbol.Compo.H)*2.0/3.0;Y=0.0}}); ("I2", {Side=Top;Offset={X=float(symbol.Compo.H)/3.0;Y=0.0}}); ("O0", {Side=Bottom;Offset={X=float(symbol.Compo.H)*2.0/3.0;Y=float(symbol.Compo.W)}});("O1", {Side=Right;Offset={X=(symbol.Compo.H);Y=float(symbol.Compo.W)-30.0}})]
|
||||
|R90 -> Map.ofList [ ("I0", {Side=Top;Offset={X=float(symbol.Compo.W)*2.0/3.0;Y=0.0}});("I1", {Side=Right;Offset={X=float(symbol.Compo.W);Y=float(symbol.Compo.H)*2.0/3.0}}); ("I2", {Side=Right;Offset={X=float(symbol.Compo.W);Y=float(symbol.Compo.H)/3.0}}); ("O0", {Side=Left;Offset={X=0.0;Y=float(symbol.Compo.H)*2.0/3.0}});("O1", {Side=Bottom;Offset={X=30.0;Y=float(symbol.Compo.H)}})]
|
||||
|R180 -> Map.ofList [ ("I0", {Side=Right;Offset={X=float(symbol.Compo.H);Y=float(symbol.Compo.W)*2.0/3.0}});("I1", {Side=Bottom;Offset={X=float(symbol.Compo.H)/3.0;Y=float(symbol.Compo.W)}}); ("I2", {Side=Bottom;Offset={X=float(symbol.Compo.H)*2.0/3.0;Y=float(symbol.Compo.W)}}); ("O0", {Side=Top;Offset={X=float(symbol.Compo.H)/3.0;Y=0.0}});("O1", {Side=Left;Offset={X=0.0;Y=30.0}})]
|
||||
|R270 -> Map.ofList [ ("I0", {Side=Bottom;Offset={X=float(symbol.Compo.W)/3.0;Y=float(symbol.Compo.H)}});("I1", {Side=Left;Offset={X=0.0;Y=float(symbol.Compo.H)/3.0}}); ("I2", {Side=Left;Offset={X=0.0;Y=float(symbol.Compo.H)*2.0/3.0}}); ("O0", {Side=Right;Offset={X=float(symbol.Compo.W);Y=float(symbol.Compo.H)/3.0}});("O1", {Side=Top;Offset={X=float(symbol.Compo.W)-30.0;Y=0.0}})]
|
||||
|
||||
let rotatePortMap' (map:Map<string,PortOrientationOffset>) (symbol:Symbol) =
|
||||
map |> Map.map (fun key port ->
|
||||
match port.Side with
|
||||
|
@ -407,27 +426,70 @@ let rotatePortMap (map:Map<string,PortOrientationOffset>) (symbol:Symbol) =
|
|||
) //MUX + ADDER requires special treatment
|
||||
|
||||
match symbol.Compo.Type with
|
||||
|MergeWires |SplitWire _ |Mux2 |NbitsAdder _ -> map
|
||||
|Mux2 -> rotatePortMapMux map symbol
|
||||
|NbitsAdder _ -> rotatePortMapAdder map symbol
|
||||
|MergeWires |SplitWire _ -> map
|
||||
|_ -> rotatePortMap' map symbol
|
||||
|
||||
|
||||
////////////////////// OLD IMPLEMENTATION -> NOT WORKING -> keep for readme.md
|
||||
let rotatePortMapOLD (map:Map<string,PortOrientationOffset>) (symbol:Symbol) =
|
||||
let h,w =
|
||||
match symbol.STransform with
|
||||
|R0|R180 -> symbol.Compo.H, symbol.Compo.W
|
||||
|R90|R270 -> symbol.Compo.W, symbol.Compo.H
|
||||
map |> Map.map (fun key port ->
|
||||
match port.Side with
|
||||
|Right -> {Side=Bottom;Offset={X=port.Offset.Y;Y=port.Offset.X}}
|
||||
// |1 -> {Side=2;Offset={X=0.0;Y=port.Offset.X}}
|
||||
|Bottom -> {Side=Left;Offset={X=float(w)-port.Offset.Y;Y=port.Offset.X}}
|
||||
|Left -> {Side=Top;Offset={X=port.Offset.Y;Y=port.Offset.X}}
|
||||
|Top -> {Side=Right;Offset={X=float(w)-port.Offset.Y;Y=port.Offset.X}}
|
||||
// |3 -> {Side=0;Offset={X=float(symbol.Compo.W);Y=port.Offset.X}}
|
||||
) //mux requires special treatment
|
||||
//////////////////////////////////////////////////////////
|
||||
let newDrawPorts (portMap: Map<string,PortOrientationOffset>) o (showInput:bool) (showOutput:bool) (symbol: Symbol) : ReactElement List=
|
||||
//----------------------------------------ROTATION HELPERS-----------------------------------------------
|
||||
///Symbol Points rotation function
|
||||
let rotatePoints points rotation =
|
||||
let rotate90 points =
|
||||
match points with
|
||||
|[x1;y1;x2;y2;x3;y3] -> [y1;x1;y2;x2;y3;x3] //constant
|
||||
|[x1;y1;x2;y2;x3;y3;x4;y4] -> [y1;x1;y2;x2;y3;x3;y4;x4] //all basic symbols
|
||||
|[x1;y1;x2;y2;x3;y3;x4;y4;x5;y5] ->[y1;x1;y5;x5;y4;x4;y3;x3;y2;x2] //input,output,wire viewer
|
||||
|[x1;y1;x2;y2;x3;y3;x4;y4;x5;y5;x6;y6] -> [y6;x6;y5;x5;y4;x4;y3;x3;y2;x2;y1;x1] //Wire label
|
||||
|[x1;y1;x2;y2;x3;y3;x4;y4;x5;y5;x6;y6;x7;y7;x8;y8] -> [y1;x1;y8;x8;y7;x7;y6;x6;y5;x5;y4;x4;y3;x3;y2;x2] //bus selector/comparator
|
||||
|_->points
|
||||
|
||||
let rotate180 points =
|
||||
match points with
|
||||
|[x1;y1;x2;y2;x3;y3] -> [x2+x2;y1;x1+x2;y2;x2+x2;y3] //constant
|
||||
|[x1;y1;x2;y2;x3;y3;x4;y4] -> [x1;y2;x2;y1;x3;y4;x4;y3] //all basic symbols
|
||||
|[x1;y1;x2;y2;x3;y3;x4;y4;x5;y5] ->[x3-x2;y1;x3;y2;x3;y4;x3-x2;y5;x1;y3] //input,output, wire viewer
|
||||
|[x1;y1;x2;y2;x3;y3;x4;y4;x5;y5;x6;y6] -> [x1;y1;x2;y2;x3;y3;x4;y4;x5;y5;x6;y6] //wire label
|
||||
|[x1;y1;x2;y2;x3;y3;x4;y4;x5;y5;x6;y6;x7;y7;x8;y8] -> [x1;y4;x4-x3;y3;x4-x2;y2;x4;y1;x5;y8;x5-x7;y7;x5-x6;y6;x8;y5] //bus selector/comparator
|
||||
|_->points
|
||||
|
||||
let rotate270 points =
|
||||
match points with
|
||||
|[x1;y1;x2;y2;x3;y3] -> [x2/2.0;y3;x2;y3+y3;x1;y3+y3] //constant
|
||||
|[x1;y1;x2;y2;x3;y3;x4;y4] -> [y2;x1;y3;x4;y4;x3;y1;x2] //all basic symbols
|
||||
|[x1;y1;x2;y2;x3;y3;x4;y4;x5;y5] ->[y3;0.0;y5;x3-x2;y4;x3;y1;x3;y2;x3-x2] //input,output, wire viewer
|
||||
|[x1;y1;x2;y2;x3;y3;x4;y4;x5;y5;x6;y6] -> [y6;x6;y5;x5;y4;x4;y3;x3;y2;x2;y1;x1] //wire label
|
||||
|[x1;y1;x2;y2;x3;y3;x4;y4;x5;y5;x6;y6;x7;y7;x8;y8] -> [y5;x8;y6;x5-x6;y7;x5-x7;y8;x4;y1;x5;y1;x4-x2;y3;x4-x3;y4;x1] //bus selector/comparator
|
||||
|_->points
|
||||
|
||||
match rotation with
|
||||
|R0 -> points
|
||||
|R90 -> rotate90 points
|
||||
|R180 -> rotate180 points
|
||||
|R270 -> rotate270 points
|
||||
|
||||
|
||||
|
||||
//------------------------------DRAWING SYMBOL HELPERS-------------------------------------
|
||||
|
||||
///convert list of points to a concatenated string to use when drawing ReactElements
|
||||
let getPointsString coordList =
|
||||
let rec combine lst =
|
||||
match lst with
|
||||
| fst::snd::tl -> (fst.ToString()+",") :: (snd.ToString()+" ") :: (combine tl)
|
||||
|[_] -> []
|
||||
|[] -> []
|
||||
combine coordList |> String.concat ""
|
||||
|
||||
|
||||
/// Text adding function with many parameters (such as bold, position and text)
|
||||
let private addText posX posY name txtPos weight size=
|
||||
let text =
|
||||
{defaultText with TextAnchor = txtPos; FontWeight = weight; FontSize = size}
|
||||
[makeText posX posY name text]
|
||||
|
||||
///Draw all ports contained in the APortOffsetMap
|
||||
let DrawPorts (portMap: Map<string,PortOrientationOffset>) o (showInput:bool) (showOutput:bool) (symbol: Symbol) : ReactElement List=
|
||||
if Map.isEmpty portMap then []
|
||||
else
|
||||
let mid = portMap |> Map.map (fun key port ->
|
||||
|
@ -436,14 +498,14 @@ let newDrawPorts (portMap: Map<string,PortOrientationOffset>) o (showInput:bool)
|
|||
)
|
||||
mid |> Map.toList |> List.map snd
|
||||
|
||||
|
||||
let newDrawPortsText (portMap:Map<string,PortOrientationOffset>) (comp: Component) symbol orientation =
|
||||
let namesM = portNameMap comp
|
||||
///Draw the corresponding text of all ports contained in APortOffsetMap
|
||||
let DrawPortsText (portMap:Map<string,PortOrientationOffset>) (comp: Component) symbol orientation =
|
||||
let namesM = portNamesMap comp
|
||||
if (Map.isEmpty portMap || Map.isEmpty namesM) then []
|
||||
else
|
||||
let inline charToInt c = int c - int '0'
|
||||
let mid = portMap |> Map.map (fun key port ->
|
||||
let name = namesM[key]
|
||||
let name = namesM[key] //TODO: Add error handling with Tryfind key
|
||||
match port.Side with
|
||||
|Right-> (addText (port.Offset.X-5.0) (port.Offset.Y-7.0) name "end" "normal" "12px")[0] //[0] to extract react element from list
|
||||
|Bottom -> (addText (port.Offset.X) (port.Offset.Y-20.0) name "Middle" "normal" "12px")[0] //they are added in a list at the end
|
||||
|
@ -452,48 +514,6 @@ let newDrawPortsText (portMap:Map<string,PortOrientationOffset>) (comp: Componen
|
|||
mid |> Map.toList |> List.map snd
|
||||
|
||||
|
||||
//------------------------------HELPER FUNCTIONS FOR DRAWING SYMBOLS-------------------------------------
|
||||
|
||||
let rotatePoints points rotation =
|
||||
let rotate90 points =
|
||||
match points with
|
||||
|[x1;y1;x2;y2;x3;y3;x4;y4] -> [y1;x1;y2;x2;y3;x3;y4;x4]
|
||||
|[x1;y1;x2;y2;x3;y3] -> [y1;x1;y2;x2;y3;x3]
|
||||
|[x1;y1;x2;y2;x3;y3;x4;y4;x5;y5] ->[y1;x1;y5;x5;y4;x4;y3;x3;y2;x2]
|
||||
|_->points
|
||||
//TO ADD OTHER SYMBOLS AS WELL
|
||||
|
||||
let rotate180 points =
|
||||
match points with
|
||||
|[x1;y1;x2;y2;x3;y3;x4;y4] -> [x1;y2;x2;y1;x3;y4;x4;y3]
|
||||
|[x1;y1;x2;y2;x3;y3] -> [x2+x2;y1;x1+x2;y2;x2+x2;y3]
|
||||
|[x1;y1;x2;y2;x3;y3;x4;y4;x5;y5] ->[x3-x2;y1;x3;y2;x3;y4;x3-x2;y5;x1;y3] //input,output
|
||||
|_->points
|
||||
//TO ADD OTHER SYMBOLS AS WELL
|
||||
|
||||
let rotate270 points =
|
||||
match points with
|
||||
|[x1;y1;x2;y2;x3;y3;x4;y4] -> [y2;x1;y3;x4;y4;x3;y1;x2]
|
||||
|[x1;y1;x2;y2;x3;y3] -> [x2/2.0;y3;x2;y3+y3;x1;y3+y3]
|
||||
|[x1;y1;x2;y2;x3;y3;x4;y4;x5;y5] ->[y3;0.0;y5;x3-x2;y4;x3;y1;x3;y2;x3-x2] //input,output
|
||||
|_->points
|
||||
//TO ADD OTHER SYMBOLS AS WELL
|
||||
|
||||
match rotation with
|
||||
|R0 -> points
|
||||
|R90 -> rotate90 points
|
||||
|R180 -> rotate180 points
|
||||
|R270 -> rotate270 points
|
||||
|
||||
let getPointsString coordList =
|
||||
let rec combine lst =
|
||||
match lst with
|
||||
| fst::snd::tl -> (fst.ToString()+",") :: (snd.ToString()+" ") :: (combine tl)
|
||||
|[_] -> []
|
||||
|[] -> []
|
||||
combine coordList |> String.concat ""
|
||||
|
||||
|
||||
let private createPolygon points colour opacity =
|
||||
[makePolygon points {defaultPolygon with Fill = colour; FillOpacity = opacity}]
|
||||
|
||||
|
@ -504,15 +524,26 @@ let createBiColorPolygon points colour strokeColor opacity strokeWidth=
|
|||
[makePolygon points {defaultPolygon with Fill = colour; FillOpacity = opacity; StrokeWidth = strokeWidth}]
|
||||
|
||||
|
||||
let addClock posX posY colour opacity =
|
||||
let points = (sprintf "%i,%i %i,%i %i,%i" posX (posY-1) (posX+8) (posY-7) posX (posY-13))
|
||||
createPolygon points colour opacity
|
||||
|> List.append (addText (float(posX+10)) (float(posY-13)) " clk" "start" "normal" "12px")
|
||||
let drawClock w h rotation colour opacity =
|
||||
let clocktext w h rotation =
|
||||
match rotation with
|
||||
|R0 -> addText (10.0) (h-13.0) " clk" "start" "normal" "12px"
|
||||
|R90 -> addText (8.0) (10.0) " clk" "middle" "normal" "12px"
|
||||
|R180 -> addText (w-10.0) (0.0) " clk" "end" "normal" "12px"
|
||||
|R270 -> addText (h-8.0) (w-20.0) " clk" "middle" "normal" "12px"
|
||||
|
||||
let clockpoints =
|
||||
match rotation with
|
||||
|R0 -> [0.0;h-1.0;8.0;h-7.0;0.0;h-13.0]
|
||||
|R90 -> [(1.0);(0.0);(7.0);(8.0);(13.0);(0.0)]
|
||||
|R180 -> [w;(1.0);w-8.0;(7.0);w;(13.0)]
|
||||
|R270 -> [(h-1.0);w;(h-7.0);(w-8.0);(h-13.0);w]
|
||||
|
||||
createPolygon (getPointsString clockpoints) colour opacity
|
||||
|> List.append (clocktext w h rotation)
|
||||
|
||||
|
||||
let addInvertorNew w h rotation colour opacity =
|
||||
// let points = (sprintf "%i,%i %i,%i %i,%i" posX (posY) (posX+9) (posY) posX (posY-8))
|
||||
// let w,h = float(width),float(height)
|
||||
let addInvertor w h rotation colour opacity =
|
||||
let points =
|
||||
match rotation with
|
||||
|R0 -> [w;h/2.0;w+9.0;h/2.0;w;h/2.0-8.0]
|
||||
|
@ -521,8 +552,8 @@ let addInvertorNew w h rotation colour opacity =
|
|||
|R270 -> [w/2.0;0.0;w/2.0;(-9.0);w/2.0-8.0;0.0]
|
||||
createPolygon (getPointsString points) colour opacity
|
||||
|
||||
let addConstantLineNew w h rotation opacity =
|
||||
// let points = (sprintf "%i,%f %i,%f" posX1 posY posX2 posY)
|
||||
|
||||
let addConstantLine w h rotation opacity =
|
||||
let points =
|
||||
match rotation with
|
||||
|R0 -> [w/2.0;h/2.0;w;h/2.0]
|
||||
|
@ -531,13 +562,15 @@ let addConstantLineNew w h rotation opacity =
|
|||
|R270 -> [w/2.0;h/2.0;w/2.0;0.0]
|
||||
createPolygon (getPointsString points) "lightgray" opacity
|
||||
|
||||
|
||||
let drawGateType w h comp =
|
||||
let gType = gateDecoderType comp
|
||||
let gType = getTitle comp
|
||||
let posX,posY =
|
||||
match comp.Type with
|
||||
|_ -> (w/2.0), (h/2.0 - 7.0)
|
||||
addText posX posY gType "middle" "bold" "14px"
|
||||
|
||||
|
||||
let outlineColor (color:string) =
|
||||
match color.ToLower() with
|
||||
| "lightgray" | "lightgrey" -> "black"
|
||||
|
@ -550,46 +583,24 @@ let addHorizontalColorLine posX1 posX2 posY opacity (color:string) = // TODO: Li
|
|||
let olColor = outlineColor color
|
||||
[makePolygon points {defaultPolygon with Fill = "olcolor"; Stroke=olColor; StrokeWidth = "2.0"; FillOpacity = opacity}]
|
||||
|
||||
|
||||
let drawLabel label width height rotation =
|
||||
match rotation with
|
||||
|R0 -> addText (width/2.0) (-20.0) (label) "middle" "normal" "16px"
|
||||
|R90 -> addText (width+5.0) (height/2.0 - 8.0) label "Start" "normal" "16px"
|
||||
|R180 -> addText (width/2.0) (height+10.0) (label) "middle" "normal" "16px"
|
||||
|R270 -> addText (-5.0) (height/2.0 - 8.0) label "End" "normal" "16px"
|
||||
|
||||
let drawLabel label width height rotation =
|
||||
match rotation with
|
||||
|R0 -> addText (width/2.0) (-20.0) (label) "middle" "normal" "16px"
|
||||
|R90 -> addText (width+5.0) (height/2.0 - 8.0) label "Start" "normal" "16px"
|
||||
|R180 -> addText (width/2.0) (height+10.0) (label) "middle" "normal" "16px"
|
||||
|R270 -> addText (-5.0) (height/2.0 - 8.0) label "End" "normal" "16px"
|
||||
|
||||
|
||||
/// --------------------------------------- SYMBOL DRAWING ------------------------------------------------------ ///
|
||||
let compSymbol (symbol:Symbol) (comp:Component) (colour:string) (showInputPorts:bool) (showOutputPorts:bool) (opacity: float)=
|
||||
// match comp.Type with
|
||||
// | Input (x) -> drawInput comp x comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol
|
||||
// | Output (x) -> drawInput comp x comp.H comp.W ((symbol.STransform+2)%4) colour opacity showInputPorts showOutputPorts symbol
|
||||
// | Mux2 -> drawMux comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol
|
||||
// | Demux2 -> drawDemux comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol
|
||||
// | NbitsAdder _ -> drawBasic comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol
|
||||
// | Viewer (x) -> drawViewer comp x comp.H comp.W ((symbol.STransform+2)%4) colour opacity showInputPorts showOutputPorts symbol
|
||||
// | Decode4 | NbitsXor _ | NbitsAdder _ -> drawBasic comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol
|
||||
// | And | Or |Xor -> drawBasic comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol
|
||||
// | Nand | Nor | Not | Xnor -> drawBasicInverted comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol
|
||||
// | BusSelection _ |BusCompare _ -> drawBus comp comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol
|
||||
// |Constant1 (_,_,txt) -> drawConstant comp txt comp.H comp.W (symbol.STransform) colour opacity showInputPorts showOutputPorts symbol
|
||||
// |_ -> []
|
||||
// | _ -> []
|
||||
// | _ -> []
|
||||
let drawSymbol (symbol:Symbol) (comp:Component) (colour:string) (showInputPorts:bool) (showOutputPorts:bool) (opacity: float)=
|
||||
|
||||
let h = (comp.H)
|
||||
let w = (comp.W)
|
||||
let halfW = (comp.W/2)
|
||||
let halfH = (comp.H/2)
|
||||
let h = float(comp.H) //height
|
||||
let w = float(comp.W) //width
|
||||
|
||||
let hF = float(comp.H) //float representation of height
|
||||
let wF = float(comp.W) //float representation of width
|
||||
let halfWF = float(comp.W/2) //float representation of halfWidth
|
||||
let halfHF = float(comp.H/2) //float representation of halfHeight
|
||||
|
||||
let rotation = symbol.STransform
|
||||
|
||||
let hR,wR = match symbol.STransform with |R90|R270 -> w,h |_ -> h,w
|
||||
let hR,wR = match symbol.STransform with |R90|R270 -> w,h |_ -> h,w //new height,width after rotation
|
||||
|
||||
let mergeSplitLine posX1 posX2 posY msb lsb =
|
||||
let text =
|
||||
|
@ -600,26 +611,28 @@ let compSymbol (symbol:Symbol) (comp:Component) (colour:string) (showInputPorts:
|
|||
addHorizontalColorLine posX1 posX2 (posY*float(h)) opacity colour @
|
||||
addText (float (posX1 + posX2)/2.0) (posY*float(h)-11.0) text "middle" "bold" "9px"
|
||||
|
||||
|
||||
let points = // Points that specify each symbol
|
||||
// Points that specify each symbol
|
||||
let points =
|
||||
match comp.Type with
|
||||
| Input _ -> rotatePoints [0.0; 0.0; (float(w)*(0.66)); 0.0; float(w); float(h)/2.0; (float(w)*(0.66)); float(h); 0.0; float(h)] rotation
|
||||
| Constant1 _ -> rotatePoints [0.0; 0.0; float(w)/2.0; float(h)/2.0; 0.0; float(h)] rotation
|
||||
| IOLabel -> rotatePoints [float(w)*(0.33); 0.0; 0.0; float(h)/2.0; (float(w)*(0.33)); float(h); (float(w)*(0.66)); float(h); float(w); float(h)/2.0; (float(w)*(0.66)); 0.0] rotation
|
||||
| Output _ -> rotatePoints [0.0; 0.0; (float(w)*(0.66)); 0.0; float(w); float(h)/2.0; (float(w)*(0.66)); float(h); 0.0; float(h)] (stransform_fsm(stransform_fsm(rotation))) //hack for rotation to work
|
||||
| Viewer _ -> rotatePoints [0.0; 0.0; (float(w)*(0.8)); 0.0; float(w); float(h)/2.0; (float(w)*(0.8)); float(h); 0.0; float(h)] (stransform_fsm(stransform_fsm(rotation))) //hack for rotation to work
|
||||
| MergeWires -> [halfWF; ((1.0/6.0)*(hF)); halfWF; ((5.0/6.0)*(hF))]
|
||||
| SplitWire _ -> [halfWF; ((1.0/6.0)*(hF)); halfWF; ((5.0/6.0)*(hF)); 0.0]
|
||||
| Demux2 -> rotatePoints [0.0; (float(h)*0.2); float(w); 0.0; float(w); float(h); 0.0; (float(h)*0.8)] rotation
|
||||
| Mux2 -> rotatePoints [0.0; 0.0; float(w); (float(h)*0.2); float(w); (float(h)*0.8); 0.0; float(h)] rotation
|
||||
| Input _ -> rotatePoints [0.0; 0.0; (w*0.66); 0.0; w; h/2.0; (w*0.66); h; 0.0; h] rotation
|
||||
| Constant1 _ -> rotatePoints [0.0; 0.0; (w/2.0); (h/2.0); 0.0; h] rotation
|
||||
| IOLabel -> rotatePoints [(w*0.33); 0.0; (w*0.66); 0.0; w; (h/2.0); (w*0.66); h; (w*0.33); h; 0.0; (h/2.0)] rotation
|
||||
| Output _ -> rotatePoints [0.0; 0.0; (w*0.66); 0.0; w; (h/2.0); (w*0.66); h; 0.0; h] (stransform_fsm(stransform_fsm(rotation))) //hack for rotation to work -> same as input but rotated twice
|
||||
| Viewer _ -> rotatePoints [0.0; 0.0; (w*0.8); 0.0; w; (h/2.0); (w*0.8); h; 0.0; h] (stransform_fsm(stransform_fsm(rotation))) //hack for rotation to work -> same as input (resized) but rotated twice
|
||||
| MergeWires -> [(w/2.0); ((1.0/6.0)*h); (w/2.0); ((5.0/6.0)*h)] //add it to rotatePoints function when implemented
|
||||
| SplitWire _ -> [(w/2.0); ((1.0/6.0)*h); (w/2.0); ((5.0/6.0)*h); 0.0] //add it to rotatePoints function when implemented
|
||||
| Demux2 -> rotatePoints [0.0; (h*0.2); w; 0.0; w; h; 0.0; (h*0.8)] rotation
|
||||
| Mux2 -> rotatePoints [0.0; 0.0; w; (h*0.2); w; (h*0.8); 0.0; h] rotation
|
||||
// EXTENSION: |Mux4|Mux8 ->(sprintf "%i,%i %i,%f %i,%f %i,%i" 0 0 w (float(h)*0.2) w (float(h)*0.8) 0 h )
|
||||
// EXTENSION: | Demux4 |Demux8 -> (sprintf "%i,%f %i,%f %i,%i %i,%i" 0 (float(h)*0.2) 0 (float(h)*0.8) w h w 0)
|
||||
| BusSelection _ |BusCompare _ -> rotatePoints [0.0; 0.0; 0.0; float(h); (0.6*(float(w))); float(h); (0.8*(float(w))); (0.7*(float(h))); float(w); (0.7*(float(h))); float(w); (0.3*(float(h))); (0.8*(float(w))); (0.3*(float(h))); (0.6*(float(w))); 0.0] rotation
|
||||
| _ -> rotatePoints [0.0; 0.0; float(w); 0.0; float(w); float(h); 0.0; float(h)] rotation
|
||||
let additions = // Helper function to add certain characteristics on specific symbols (inverter, enables, clocks)
|
||||
| BusSelection _ |BusCompare _ -> rotatePoints [0.0; 0.0; (0.6*w); 0.0; (0.8*w); (0.3*h); w; (0.3*h); w; (0.7*h); (0.8*w); (0.7*h); (0.6*w); h; 0.0; h] rotation
|
||||
| _ -> rotatePoints [0.0; 0.0; w; 0.0; w; h; 0.0; h] rotation
|
||||
|
||||
// Helper function to add certain characteristics on specific symbols (inverter, enables, clocks)
|
||||
let extras =
|
||||
match comp.Type with
|
||||
| Constant1 (_,_,txt) -> (addConstantLineNew (float(wR)) (float(hR)) rotation opacity @ addText (float (float(w)/2.0)-5.0) (float(h)-8.0) txt "middle" "normal" "12px")
|
||||
| Nand | Nor | Xnor |Not -> (addInvertorNew (float(wR)) (float(hR)) rotation colour opacity)
|
||||
| Constant1 (_,_,txt) -> (addConstantLine (float(wR)) (float(hR)) rotation opacity @ addText (float (float(w)/2.0)-5.0) (float(h)-8.0) txt "middle" "normal" "12px")
|
||||
| Nand | Nor | Xnor |Not -> (addInvertor (float(wR)) (float(hR)) rotation colour opacity)
|
||||
| MergeWires ->
|
||||
let lo, hi =
|
||||
match symbol.InWidth0, symbol.InWidth1 with
|
||||
|
@ -628,38 +641,38 @@ let compSymbol (symbol:Symbol) (comp:Component) (colour:string) (showInputPorts:
|
|||
let msb = hi + lo - 1
|
||||
let midb = lo
|
||||
let midt = lo - 1
|
||||
mergeSplitLine 0 halfW (1.0/6.0) midt 0 @
|
||||
mergeSplitLine 0 halfW (5.0/6.0) msb midb @
|
||||
mergeSplitLine halfW w 0.5 msb 0
|
||||
mergeSplitLine 0 (int(w/2.0)) (1.0/6.0) midt 0 @
|
||||
mergeSplitLine 0 (int(w/2.0)) (5.0/6.0) msb midb @
|
||||
mergeSplitLine (int(w/2.0)) (int(w)) 0.5 msb 0
|
||||
| SplitWire mid ->
|
||||
let msb, mid' = match symbol.InWidth0 with | Some n -> n - 1, mid | _ -> -100, -50
|
||||
let midb = mid'
|
||||
let midt = mid'-1
|
||||
mergeSplitLine halfW w (1.0/6.0) midt 0 @
|
||||
mergeSplitLine halfW w (5.0/6.0) msb midb @
|
||||
mergeSplitLine 0 halfW 0.5 msb 0
|
||||
| DFF |DFFE -> (addClock 0 h colour opacity)
|
||||
| Register _ |RegisterE _ -> (addClock 0 h colour opacity)
|
||||
| ROM1 _ |RAM1 _ | AsyncRAM1 _ -> (addClock 0 h colour opacity)
|
||||
| BusSelection(x,y) -> (addText (float(wR/2)-5.0) ((float(hR)/2.7)-2.0) (bustitle x y) "middle" "normal" "12px")
|
||||
| BusCompare (_,y) -> (addText (float(wR/2)-6.0) (float(hR)/2.7-1.0) ("=" + NumberHelpers.hex(int y)) "middle" "bold" "10px")
|
||||
| Input x -> (addText (float(wR/2)) ((float(hR)/3.0)) (title "" x) "middle" "normal" "12px")
|
||||
| Output x -> (addText (float(wR/2)) ((float(hR)/3.0)) (title "" x) "middle" "normal" "12px")
|
||||
| Viewer x -> (addText (float(w/2)) ((float(h)/2.7)-1.25) (title "" x) "middle" "normal" "9px")
|
||||
mergeSplitLine (int(w/2.0)) (int(w)) (1.0/6.0) midt 0 @
|
||||
mergeSplitLine (int(w/2.0)) (int(w)) (5.0/6.0) msb midb @
|
||||
mergeSplitLine 0 (int(w/2.0)) 0.5 msb 0
|
||||
| DFF |DFFE -> (drawClock w h rotation colour opacity)
|
||||
| Register _ |RegisterE _ -> (drawClock w h rotation colour opacity)
|
||||
| ROM1 _ |RAM1 _ | AsyncRAM1 _ -> (drawClock w h rotation colour opacity)
|
||||
| BusSelection(x,y) -> (addText (wR/2.0) ((hR/2.7)-2.0) (bustitleGen x y) "middle" "normal" "12px")
|
||||
| BusCompare (_,y) -> (addText (wR/2.0) ((hR/2.7)-1.0) ("=" + NumberHelpers.hex(int y)) "middle" "bold" "10px")
|
||||
| Input (x) -> (addText (wR/2.0) (hR/3.0) (titleGen "" x) "middle" "normal" "12px")
|
||||
| Output (x) -> (addText (wR/2.0) ((float(hR)/3.0)) (titleGen "" x) "middle" "normal" "12px")
|
||||
| Viewer (x) -> (addText (w/2.0) ((float(h)/2.7)-1.25) (titleGen "" x) "middle" "normal" "9px")
|
||||
| _ -> []
|
||||
|
||||
let olColour, strokeWidth =
|
||||
let borderColour, strokeWidth =
|
||||
match comp.Type with
|
||||
| SplitWire _ | MergeWires -> outlineColor colour, "2.0"
|
||||
| _ -> "black", "1.0"
|
||||
|
||||
// Put everything together
|
||||
(newDrawPorts symbol.APortOffsetsMap symbol.STransform showInputPorts showOutputPorts symbol)
|
||||
|> List.append (newDrawPortsText symbol.APortOffsetsMap comp symbol symbol.STransform)
|
||||
|> List.append (drawGateType (float(wR)) (float(hR)) comp)
|
||||
|> List.append (additions)
|
||||
|> List.append (drawLabel comp.Label (float(wR)) (float(hR)) symbol.STransform)
|
||||
|> List.append (createBiColorPolygon (getPointsString points) colour olColour opacity "1.0")
|
||||
(DrawPorts symbol.APortOffsetsMap symbol.STransform showInputPorts showOutputPorts symbol) //Ports
|
||||
|> List.append (DrawPortsText symbol.APortOffsetsMap comp symbol symbol.STransform) //PortsText
|
||||
|> List.append (drawGateType (float(wR)) (float(hR)) comp) //Symbol Title - e.g. N-Bits-Adder(3..0)
|
||||
|> List.append (extras) //extra components required for specific symbol - e.g. Clock invertor etc.
|
||||
|> List.append (drawLabel comp.Label (float(wR)) (float(hR)) symbol.STransform) //Label
|
||||
|> List.append (createBiColorPolygon (getPointsString points) colour borderColour opacity "1.0") //actual symbol
|
||||
|
||||
let init () =
|
||||
{ Symbols = Map.empty; CopiedSymbols = Map.empty; Ports = Map.empty ; InputPortsConnected= Set.empty ; OutputPortsConnected = Map.empty}, Cmd.none
|
||||
|
@ -679,14 +692,14 @@ let private renderSymbol =
|
|||
fun (props : RenderSymbolProps) ->
|
||||
let symbol = props.Symbol
|
||||
let ({X=fX; Y=fY}:XYPos) = symbol.Pos
|
||||
g ([ Style [ Transform(sprintf "translate(%fpx, %fpx)" fX fY) ] ]) (compSymbol props.Symbol props.Symbol.Compo symbol.Colour symbol.ShowInputPorts symbol.ShowOutputPorts symbol.Opacity)
|
||||
g ([ Style [ Transform(sprintf "translate(%fpx, %fpx)" fX fY) ] ]) (drawSymbol props.Symbol props.Symbol.Compo symbol.Colour symbol.ShowInputPorts symbol.ShowOutputPorts symbol.Opacity)
|
||||
|
||||
, "Symbol"
|
||||
, equalsButFunctions
|
||||
)
|
||||
|
||||
/// View function for symbol layer of SVG
|
||||
let MapsIntoLists map =
|
||||
let getSymbols map =
|
||||
let listMoving =
|
||||
Map.filter (fun _ sym -> not sym.Moving) map
|
||||
|>Map.toList
|
||||
|
@ -701,7 +714,7 @@ let MapsIntoLists map =
|
|||
let view (model : Model) (dispatch : Msg -> unit) =
|
||||
let start = TimeHelpers.getTimeMs()
|
||||
model.Symbols
|
||||
|> MapsIntoLists
|
||||
|> getSymbols
|
||||
|> List.map (fun ({Id = ComponentId id} as symbol) ->
|
||||
renderSymbol
|
||||
{
|
||||
|
@ -714,7 +727,9 @@ let view (model : Model) (dispatch : Msg -> unit) =
|
|||
|> TimeHelpers.instrumentInterval "SymbolView" start
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------//
|
||||
//--------------------AP1919 CODE SECTION ENDS-------------------------------------//
|
||||
//---------------------------------------------------------------------------------//
|
||||
//---------------------------------------------------------------------------------//
|
||||
//--------------------GV319 CODE SECTION 2 STARTS-------------------------------------//
|
||||
//---------------------------------------------------------------------------------//
|
||||
|
@ -984,7 +999,7 @@ let labelGenNumber (model: Model) (compType: ComponentType) (label : string) =
|
|||
|
||||
///Generates the label for a component type
|
||||
let generateLabel (model: Model) (compType: ComponentType) : string =
|
||||
labelGenNumber model compType (prefix compType)
|
||||
labelGenNumber model compType (getLabel compType)
|
||||
|
||||
/// Interface function to paste symbols. Is a function instead of a message because we want an output
|
||||
/// Currently drag-and-drop
|
||||
|
@ -997,13 +1012,13 @@ let pasteSymbols (symModel: Model) (mPos: XYPos) : Model * ComponentId list =
|
|||
let pastedSymbol =
|
||||
{ oldSymbol with
|
||||
Id = ComponentId newId
|
||||
Compo = makeComp newPos oldSymbol.Compo.Type newId (labelGenNumber { symModel with Symbols = currSymbolModel.Symbols } oldSymbol.Compo.Type oldSymbol.Compo.Label) // TODO: Change label later
|
||||
Compo = createComponent newPos oldSymbol.Compo.Type newId (labelGenNumber { symModel with Symbols = currSymbolModel.Symbols } oldSymbol.Compo.Type oldSymbol.Compo.Label) // TODO: Change label later
|
||||
Pos = newPos
|
||||
ShowInputPorts = false
|
||||
ShowOutputPorts = false }
|
||||
|
||||
let newSymbolMap = currSymbolModel.Symbols.Add ((ComponentId newId), pastedSymbol) // List needs to be in this order
|
||||
let newPorts = addToPortModel currSymbolModel pastedSymbol
|
||||
let newPorts = addPortsToModel currSymbolModel pastedSymbol
|
||||
{ currSymbolModel with Symbols = newSymbolMap; Ports = newPorts }, pastedIdsList @ [ pastedSymbol.Id ]
|
||||
|
||||
let oldSymbolsList =
|
||||
|
@ -1058,7 +1073,7 @@ let getEquivalentCopiedPorts (model: Model) copiedIds pastedIds (InputPortId cop
|
|||
let addSymbol (model: Model) pos compType lbl =
|
||||
let newSym = createNewSymbol pos compType lbl
|
||||
let newSymbolWithMap = {newSym with APortOffsetsMap = (genAPortOffsets newSym newSym.Compo.Type)}
|
||||
let newPorts = addToPortModel model newSymbolWithMap
|
||||
let newPorts = addPortsToModel model newSymbolWithMap
|
||||
let newSymModel = Map.add newSymbolWithMap.Id newSymbolWithMap model.Symbols
|
||||
{ model with Symbols = newSymModel; Ports = newPorts }, newSymbolWithMap.Id
|
||||
|
||||
|
@ -1230,7 +1245,7 @@ let update (msg : Msg) (model : Model): Model*Cmd<'a> =
|
|||
let xyPos = {X = float comp.X; Y = float comp.Y}
|
||||
let h,w =
|
||||
if comp.H = -1 && comp.W = -1 then
|
||||
let comp' = makeComp xyPos comp.Type comp.Id comp.Label
|
||||
let comp' = createComponent xyPos comp.Type comp.Id comp.Label
|
||||
comp'.H,comp'.W
|
||||
else
|
||||
comp.H, comp.W
|
||||
|
@ -1258,7 +1273,7 @@ let update (msg : Msg) (model : Model): Model*Cmd<'a> =
|
|||
|> Map.ofList
|
||||
|
||||
let folder currModel sym =
|
||||
{ currModel with Ports = addToPortModel currModel sym }
|
||||
{ currModel with Ports = addPortsToModel currModel sym }
|
||||
|
||||
let newModel = ( model, symbolList ) ||> List.fold folder
|
||||
{ newModel with Symbols = symbolMap }, Cmd.none
|
||||
|
|
Loading…
Reference in a new issue