first commit
This commit is contained in:
commit
b1c14f5aba
12 changed files with 1040 additions and 0 deletions
40
src/ClkDivider.bs
Normal file
40
src/ClkDivider.bs
Normal file
|
@ -0,0 +1,40 @@
|
|||
package ClkDivider(mkClkDivider, ClkDivider(..)) where
|
||||
|
||||
interface (ClkDivider :: # -> *) hi =
|
||||
{
|
||||
reset :: Action
|
||||
;isAdvancing :: Bool
|
||||
;isHalfCycle :: Bool
|
||||
}
|
||||
|
||||
mkClkDivider :: Handle -> Module (ClkDivider hi)
|
||||
mkClkDivider fileHandle = do
|
||||
counter <- mkReg(0 :: UInt (TLog hi))
|
||||
let hi_value :: UInt (TLog hi) = (fromInteger $ valueOf hi)
|
||||
let half_hi_value :: UInt (TLog hi) = (fromInteger $ valueOf (TDiv hi 2))
|
||||
|
||||
let val :: Real = (fromInteger $ valueOf hi)
|
||||
let msg = "Clock Div Period : " + (realToString val) + "\n"
|
||||
|
||||
hPutStr fileHandle msg
|
||||
hPutStr fileHandle genModuleName
|
||||
|
||||
addRules $
|
||||
rules
|
||||
{-# ASSERT fire when enabled #-}
|
||||
{-# ASSERT no implicit conditions #-}
|
||||
"tick" : when True ==> action
|
||||
$display (counter)
|
||||
counter := if (counter == hi_value)
|
||||
then 0
|
||||
else counter + 1
|
||||
|
||||
return $
|
||||
interface ClkDivider
|
||||
reset :: Action
|
||||
reset = do
|
||||
counter := 0
|
||||
|
||||
isAdvancing :: Bool
|
||||
isAdvancing = (counter == hi_value)
|
||||
isHalfCycle = (counter == half_hi_value)
|
53
src/Deserializer.bs
Normal file
53
src/Deserializer.bs
Normal file
|
@ -0,0 +1,53 @@
|
|||
package Deserializer(
|
||||
mkDeserialize,
|
||||
IDeserializer(..),
|
||||
State(..))
|
||||
where
|
||||
|
||||
import ClkDivider
|
||||
import State
|
||||
|
||||
|
||||
interface (IDeserializer :: # -> # -> *) clkFreq baudRate =
|
||||
get :: Bit 8
|
||||
putBitIn :: (Bit 1) -> Action {-# always_enabled, always_ready #-}
|
||||
|
||||
mkDeserialize :: Handle -> Module (IDeserializer clkFreq baudRate)
|
||||
mkDeserialize fileHandle = do
|
||||
ftdiRxIn :: Wire(Bit 1) <- mkBypassWire
|
||||
shiftReg :: Reg(Bit 8) <- mkReg(0)
|
||||
ftdiState <- mkReg(IDLE)
|
||||
|
||||
clkDivider :: (ClkDivider (TDiv clkFreq baudRate)) <- mkClkDivider fileHandle
|
||||
|
||||
addRules $
|
||||
rules
|
||||
|
||||
{-# ASSERT fire when enabled #-}
|
||||
"IDLE" : when (ftdiState == IDLE), (ftdiRxIn == 0) ==>
|
||||
do
|
||||
clkDivider.reset
|
||||
ftdiState := ftdiStateNext ftdiState
|
||||
|
||||
{-# ASSERT fire when enabled #-}
|
||||
"NOT IDLE" : when (ftdiState /= IDLE), (clkDivider.isAdvancing) ==>
|
||||
do
|
||||
ftdiState := ftdiStateNext ftdiState
|
||||
|
||||
{-# ASSERT fire when enabled #-}
|
||||
"SAMPLING" : when
|
||||
DATA(n) <- ftdiState,
|
||||
n >= 0,
|
||||
n <= 7,
|
||||
let sampleTrigger = clkDivider.isHalfCycle
|
||||
in sampleTrigger
|
||||
==>
|
||||
do
|
||||
shiftReg := ftdiRxIn ++ shiftReg[7:1]
|
||||
|
||||
return $
|
||||
interface IDeserializer
|
||||
{get = shiftReg when (ftdiState == STOP), (clkDivider.isAdvancing)
|
||||
;putBitIn bit =
|
||||
ftdiRxIn := bit
|
||||
}
|
52
src/Serializer.bs
Normal file
52
src/Serializer.bs
Normal file
|
@ -0,0 +1,52 @@
|
|||
package Serializer(
|
||||
mkSerialize,
|
||||
ISerializer(..),
|
||||
State(..))
|
||||
where
|
||||
|
||||
import ClkDivider
|
||||
import State
|
||||
|
||||
serialize :: State -> Bit 8 -> Bit 1
|
||||
serialize ftdiState dataReg =
|
||||
case ftdiState of
|
||||
START -> 1'b0
|
||||
(DATA n) -> dataReg[n:n]
|
||||
_ -> 1'b1
|
||||
|
||||
interface (ISerializer :: # -> # -> *) clkFreq baudRate =
|
||||
putBit8 :: (Bit 8) -> Action {-# always_enabled, always_ready #-}
|
||||
bitLineOut :: Bit 1 {-# always_ready #-}
|
||||
|
||||
mkSerialize :: Handle -> Module (ISerializer clkFreq baudRate)
|
||||
mkSerialize fileHandle = do
|
||||
|
||||
ftdiTxOut :: Wire(Bit 1) <- mkBypassWire
|
||||
dataReg :: Reg(Bit 8) <- mkReg(0)
|
||||
ftdiState <- mkReg(IDLE)
|
||||
clkDivider :: (ClkDivider (TDiv clkFreq baudRate)) <- mkClkDivider fileHandle
|
||||
|
||||
addRules $
|
||||
rules
|
||||
{-# ASSERT fire when enabled #-}
|
||||
"ADVANCE UART STATE WHEN NOT IDLE" : when
|
||||
(ftdiState /= IDLE),
|
||||
(clkDivider.isAdvancing) ==>
|
||||
do
|
||||
ftdiState := ftdiStateNext ftdiState
|
||||
|
||||
{-# ASSERT fire when enabled #-}
|
||||
"BIT LINE" : when True ==>
|
||||
do
|
||||
ftdiTxOut := serialize ftdiState dataReg
|
||||
|
||||
return $
|
||||
interface ISerializer
|
||||
putBit8 bit8Val =
|
||||
do
|
||||
clkDivider.reset
|
||||
dataReg := bit8Val
|
||||
ftdiState := ftdiStateNext ftdiState
|
||||
when (ftdiState == IDLE)
|
||||
bitLineOut = ftdiTxOut
|
||||
|
32
src/State.bsv
Normal file
32
src/State.bsv
Normal file
|
@ -0,0 +1,32 @@
|
|||
package State;
|
||||
export State(..);
|
||||
|
||||
export ftdiStateNext;
|
||||
|
||||
typedef union tagged {
|
||||
void IDLE;
|
||||
void START;
|
||||
UInt#(TLog#(8)) DATA;
|
||||
void PARITY;
|
||||
void STOP;
|
||||
} State deriving (Bits, Eq, FShow);
|
||||
|
||||
function State ftdiStateNext(State state);
|
||||
return
|
||||
case (state) matches
|
||||
tagged IDLE : START;
|
||||
tagged START : DATA(0);
|
||||
tagged DATA .n :
|
||||
begin
|
||||
if (n == 7)
|
||||
PARITY;
|
||||
else
|
||||
DATA(n + 1);
|
||||
end
|
||||
tagged PARITY : STOP;
|
||||
tagged STOP : IDLE;
|
||||
endcase
|
||||
;
|
||||
endfunction
|
||||
|
||||
endpackage
|
76
src/Top.bsv
Normal file
76
src/Top.bsv
Normal file
|
@ -0,0 +1,76 @@
|
|||
package Top;
|
||||
export mkTop;
|
||||
|
||||
export ITop(..);
|
||||
|
||||
// export mkSim;
|
||||
|
||||
import Deserializer::*;
|
||||
|
||||
import Serializer::*;
|
||||
|
||||
typedef 25000000 FCLK;
|
||||
|
||||
typedef 9600 BAUD;
|
||||
|
||||
interface ITop;
|
||||
(* always_ready *)
|
||||
method Bit#(1) ftdi_rxd();
|
||||
(* always_ready *)
|
||||
method Bit#(8) led();
|
||||
(* always_enabled , always_ready *)
|
||||
method Action ftdi_txd(Bit#(1) bitIn);
|
||||
endinterface: ITop
|
||||
|
||||
(* synthesize *)
|
||||
module mkTop(ITop);
|
||||
Handle fileHandle <- openFile("compile.log", WriteMode);
|
||||
IDeserializer#(FCLK, BAUD) deserializer <- mkDeserialize(fileHandle);
|
||||
ISerializer#(FCLK, BAUD) serializer <- mkSerialize(fileHandle);
|
||||
|
||||
Wire#(Bit#(1)) ftdiBitIn <- mkBypassWire;
|
||||
Reg#(Bit#(8)) rxReg <- mkReg(0);
|
||||
|
||||
messageM("Hallo!!" + realToString(5));
|
||||
|
||||
rule loopback;
|
||||
rxReg <= deserializer.get;
|
||||
serializer.putBit8(deserializer.get);
|
||||
endrule
|
||||
|
||||
rule txOut;
|
||||
deserializer.putBitIn(ftdiBitIn);
|
||||
endrule
|
||||
|
||||
method Bit#(1) ftdi_rxd;
|
||||
return serializer.bitLineOut;
|
||||
endmethod
|
||||
|
||||
method Bit#(8) led;
|
||||
return rxReg;
|
||||
endmethod
|
||||
|
||||
method Action ftdi_txd(Bit#(1) bitIn);
|
||||
ftdiBitIn <= bitIn;
|
||||
endmethod
|
||||
endmodule
|
||||
|
||||
// module mkSim(Empty);
|
||||
// (actionvalue
|
||||
// Reg#(UInt#(3)) count();
|
||||
// mkReg#(0) the_count(count);
|
||||
// addRules(rules
|
||||
// rule count (True);
|
||||
// count <= unpack({1'b1, (pack(count))[2:1]});
|
||||
// ($display)(count);
|
||||
// endrule: count
|
||||
// rule end_sim (count == 6);
|
||||
// ($finish)();
|
||||
// endrule: end_sim
|
||||
// endrules);
|
||||
// return(interface Empty
|
||||
// endinterface: Empty);
|
||||
// endactionvalue);
|
||||
// endmodule: mkSim
|
||||
|
||||
endpackage
|
Reference in a new issue