Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
65 lines (54 sloc) 2.52 KB
module Hardware (topEntity) where
import CLaSH.Prelude
import Hardware.CPU (cpu, Halt(DoHalt, Don'tHalt))
import Hardware.MMU (
RAMStatus(NoUpdate, ReadComplete, WriteComplete),
RAMAction(W,R,X) )
import Hardware.Model (
Output, W, Ptr(Ptr), SKI, Output(..),
binarize, unbinarize, binarizePtr )
import Hardware.MemoryEmulator.RAM (ram)
import Hardware.MemoryEmulator.Default (defaultContents)
-- topEntity :: Signal RAMStatus -> Signal (RAMAction, Maybe Output)
-- topEntity = cpu
type RAMStatusBits = (Bit, Bit, BitVector 64) -- Enable, read/write, data
type RAMActionBits = (Bit, Bit, BitVector 30, BitVector 64) -- Enable, read/write, ptr, data
type OutputBits = (Bit, Unsigned 32) -- Enable, data
type HaltBit = Bit
ramstatus :: RAMStatusBits -> RAMStatus
ramstatus (0,_,_) = NoUpdate
ramstatus (1,0,s) = ReadComplete (unbinarize s)
ramstatus (1,1,_) = WriteComplete
ramaction :: RAMAction -> RAMActionBits
ramaction (R ptr) = (1, 0, binarizePtr ptr, 0)
ramaction (W ptr x) = (1, 1, binarizePtr ptr, binarize x)
ramaction (X) = (0, 0, 0, 0)
output :: Maybe Output -> OutputBits
output Nothing = (0, 0)
output (Just (Output o)) = (1, o)
halt :: Halt -> HaltBit
halt DoHalt = 1
halt Don'tHalt = 0
-- NB: cpu :: Signal RAMStatus -> Signal (RAMAction, Maybe Output, Halt)
cpuHardware :: Signal RAMStatusBits
-> Signal (RAMActionBits, OutputBits, HaltBit)
cpuHardware = fmap convert . cpu . fmap ramstatus
where convert (ram,out,done) = (ramaction ram, output out, halt done)
-- NB: For portability, we are not using "real" external RAM; we are using
-- block RAM. Block RAM is fast single-cycle RAM built into the FPGA. See
-- the definition of "ram"; we're using Clash's blockRam primitive.
-- This generates code that most synthesis tools will recognize
-- as block RAM. Unfortunately, most FPGAs only have block RAM in the hundreds
-- of kilobits or low megabits.
-- If you'd like, you can replace this with actual RAM hardware for your FPGA.
-- This project uses 30-bit pointers to 64-bit words, so you could potentially
-- use up to 8GiB without much trouble. However, be warned that real RAM
-- tends to be much more complicated and platform-specific.
ramHardware :: Signal RAMActionBits -> Signal RAMStatusBits
ramHardware = ram defaultContents
-- The thing that gets synthesized to an HDL
topEntity :: Signal (OutputBits, HaltBit)
topEntity = bundle (output, halt)
where
(ramRequest, output, halt) = unbundle $ cpuHardware ramResponse
ramResponse = ramHardware ramRequest