package AvalonTimer; import GetPut::*; import ClientServer::*; import Avalon2ClientServer::*; // word address width `define addr_width 2 (* always_ready, always_enabled *) interface AvalonTimerIfc; interface AvalonSlaveIfc#(`addr_width) avs; // AvalonSlave physical interface method UInt#(26) coe_leds; // exported signals (coe=Conduit Output Export) endinterface // tell Bluespec to produce a synthesizable design // and set clock and reset names to what SOPC builder expects (* synthesize, reset_prefix = "csi_clockreset_reset_n", clock_prefix = "csi_clockreset_clk" *) module mkAvalonTimer(AvalonTimerIfc); AvalonSlave2ClientIfc#(`addr_width) slave <- mkAvalonSlave2Client; Reg#(UInt#(32)) timer <- mkReg(0); Reg#(Bool) run_timer <- mkReg(False); Wire#(Maybe#(UInt#(32))) set_timer <- mkDWire(tagged Invalid); PulseWire timer_stop <- mkPulseWire; PulseWire timer_start <- mkPulseWire; rule handle_avalon_requests; let req <- slave.client.request.get(); ReturnedDataT rtn = tagged Invalid; case(tuple2(req.addr, req.rw)) tuple2(0, MemWrite) : set_timer <= tagged Valid req.data; tuple2(0, MemRead) : rtn = tagged Valid timer; tuple2(1, MemWrite) : if(req.data==0) timer_stop.send; else timer_start.send; tuple2(1, MemRead) : begin rtn = tagged Valid timer; timer_stop.send(); end endcase slave.client.response.put(rtn); endrule (* no_implicit_conditions *) rule handle_timer (True); let running = !timer_stop && (timer_start || run_timer); if(isValid(set_timer)) timer <= fromMaybe(?,set_timer); else if(running) timer <= timer+1; run_timer <= running; endrule // pass physical Avalon interface out of this module interface avs = slave.avs; // export upper bits of timer to LEDs method UInt#(26) coe_leds; return truncate(timer>>6); endmethod endmodule endpackage: AvalonTimer