-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAlu.hs
More file actions
79 lines (54 loc) · 1.78 KB
/
Alu.hs
File metadata and controls
79 lines (54 loc) · 1.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RecordWildCards #-}
module Alu where
import CLaSH.Prelude
import CLaSH.Sized.Unsigned
import qualified Data.List as L
import Text.Printf
import Debug.Trace
import Types
--
-- Left Shift should be performed as an add
--
data AluOp = AluADD
| AluSUB -- Real 6502 Doesn't have this explicitly - adding it here allows us to not model the separate inverter
| AluOR
| AluAND
| AluXOR
| AluRSHIFT
| AluNOP
type VecWord = Vec 32 Bit
-- op aIn bIn cIn (out, carry, overflow)
alu :: AluOp -> WordSize -> WordSize -> Bit -> (WordSize, Bit, Bit)
alu op aIn bIn cIn = case op of
AluNOP -> (aIn, 0, 0)
AluOR -> (aIn .|. bIn, 0, 0)
AluAND -> (aIn .&. bIn, 0, 0)
AluXOR -> (aIn `xor` bIn, 0, 0)
AluRSHIFT -> (pack (cIn +>> v), v !! (maxIndex v), 0) where
v = unpack aIn :: VecWord
-- Add/Sub case
_ -> add aIn (complement bIn') cIn where
bIn' = case op of
AluSUB -> complement bIn
AluADD -> bIn
-- aIn bIn cIn bcd -> (res, cOut, vOut)
add :: WordSize -> WordSize -> Bit -> (WordSize, Bit, Bit)
add aIn bIn cIn = (res, cOut, vOut) where
(res, cOut, vOut) = adder cIn aIn bIn
adder :: Bit -> WordSize -> WordSize -> (WordSize, Bit, Bit)
adder cIn xV yV = (pack (reverse sum), cOut, vOut) where
x = reverse $ unpack xV
y = reverse $ unpack yV
res = zipWith3 fullAdder (cIn +>> carries) x y
(sum, carries) = unzip res
cOut = carries !! (maxIndex carries)
vOut = cOut `xor` (carries !! ((maxIndex carries)-1))
fullAdder :: Bit -> Bit -> Bit -> (Bit, Bit)
fullAdder cIn x y = (s, cOut) where
p = x `xor` y
s = p `xor`cIn
cOut = if p == low then y else cIn