/*=========================================================================*/ /*=== DE248 Support Library ==============================================*/ /*=========================================================================*/ /* * FILE: support.v * PROGRAMMER: William L. Bahn * * This file contains just those modules from other, more generic, * library files that are needed for the DE248. The purpose for * doing this is to make the distribution files more compact. * * CONTENTS: * From: registers.v * - RSFF(Q, S, R, rst, clk); * - DFFRen(Q, D, en, rst, clk); * - Reg4(Q, D, en, rst, clk); * - Reg8(Q, D, en, rst, clk); * - Reg16(Q, D, en, rst, clk); * - ShiftReg10(Sout, Sin, Q, D, Shift, Load, rst, clk); * - ShiftReg16LSB(Sout, Sin, Q, D, Shift, Load, rst, clk); * - DualPortBlockRAM512x64(WA, Din, WE, RA, Dout, clk); * From: counter.v * - Counter12(Q, en, rst, clk); * - PulseGen8(Q, Period, en, rst, clk); * - PulseGen16(Q, Period, en, rst, clk); * - PulseGen24(Q, Period, en, rst, clk); * - Binary2Gray12(Gray, Binary, rst, clk); * - Gray2Binary12(Binary, Gray, rst, clk); * From: muxus.v * - MUX2(Q, D1, D0, Sel); * - MUX4(Q, D3, D2, D1, D0, Sel); * - MUX2TAP(Q, D, Sel); * - MUX4TAP(Q, D, Sel); * - MUX2x2(Q, D1, D0, Sel); * - MUX2x8(Q, D1, D0, Sel); * - MUX2x16(Q, D1, D0, Sel); * - MUX4x2(Q, D3, D2, D1, D0, Sel); * - MUX4x8(Q, D3, D2, D1, D0, Sel); * - MUX16x8 * From: fifos.v * - FIFO16x24(Dout, Din, FF, AF, HF, AE, EF, Push, Pop, Dump, clk); * - FIFO16x32(Dout, Din, FF, AF, HF, AE, EF, Push, Pop, Dump, clk); * From: mmv.v * - OneShot(Q, Start, Stop, rst, clk); * - FireAndAcknowledge(Q, Fire, Ack, rst, clk); */ /*=========================================================================*/ /*=== From the REGISTERS LIBRARY ========================================*/ /*=========================================================================*/ module RSFF(Q, S, R, rst, clk); output Q; input S, R; input rst, clk; parameter LO = 1'b0, HI = 1'b1; reg Q_int; assign Q = Q_int; always @ (posedge clk) begin if ((rst == HI)||(R == HI)) Q_int <= LO; else if (S == HI) Q_int <= HI; else Q_int <= Q_int; end endmodule module DFFRen(Q, D, en, rst, clk); output Q; input D, en, rst, clk; reg Q_int; assign Q = Q_int; always @ (posedge clk or posedge rst) begin if (rst == 1) Q_int <= 0; else if (en == 1) Q_int <= D; else Q_int <= Q_int; end endmodule module Reg4(Q, D, en, rst, clk); parameter REGWIDTH = 4; input clk, en, rst; input [(REGWIDTH-1):0] D; output [(REGWIDTH-1):0] Q; reg [(REGWIDTH-1):0] Q_int; assign Q = (rst == 0)? Q_int : 4'd0; always @ (posedge clk) begin if (rst == 1) Q_int <= 4'd0; else if (en == 1) Q_int <= D; else Q_int <= Q_int; end endmodule module Reg8(Q, D, en, rst, clk); parameter REGWIDTH = 8; input clk, en, rst; input [(REGWIDTH-1):0] D; output [(REGWIDTH-1):0] Q; reg [(REGWIDTH-1):0] Q_int; assign Q = (rst == 0)? Q_int : 8'd0; always @ (posedge clk) begin if (rst == 1) Q_int <= 8'd0; else if (en == 1) Q_int <= D; else Q_int <= Q_int; end endmodule module Reg16(Q, D, en, rst, clk); parameter REGWIDTH = 16; input clk, en, rst; input [(REGWIDTH-1):0] D; output [(REGWIDTH-1):0] Q; reg [(REGWIDTH-1):0] Q_int; assign Q = (rst == 0)? Q_int : 16'd0; always @ (posedge clk) begin if (rst == 1) Q_int <= 16'd0; else if (en == 1) Q_int <= D; else Q_int <= Q_int; end endmodule module ShiftReg10(Sout, Sin, Q, D, Shift, Load, rst, clk); input Sin; output Sout; output [9:0] Q; input [9:0] D; input Shift, Load, rst, clk; reg [9:0] Q_int; assign Q = (rst == 0)? Q_int: 10'd0; assign Sout = Q_int[0]; always @ (posedge clk) begin if (rst == 1) Q_int <= 10'd0; else if (Load == 1) Q_int <= D; else if (Shift == 1) Q_int <= {Sin,Q_int[9:1]}; else Q_int <= Q_int; end endmodule module ShiftReg16DIR(Sout, Sin, Q, D, Shift, Load, Dir, rst, clk); input Sin; output Sout; output [15:0] Q; input [15:0] D; input Shift, Load, Dir, rst, clk; reg [15:0] Q_int; assign Q = Q_int; assign Sout = (Dir == 0)? Q_int[0] : Q_int[15]; always @ (posedge clk) begin if (rst == 1) Q_int <= 16'd0; else if (Load == 1) Q_int <= D; else if (Shift == 1) if (Dir == 0) Q_int <= {Sin, Q_int[15:1]}; else Q_int <= {Q_int[14:0], Sin}; else Q_int <= Q_int; end endmodule module ShiftReg16LSB(Sout, Sin, Q, D, Shift, Load, rst, clk); input Sin; output Sout; output [15:0] Q; input [15:0] D; input Shift, Load, rst, clk; reg [15:0] Q_int; assign Q = (rst == 0)? Q_int: 16'd0; assign Sout = Q_int[0]; always @ (posedge clk) begin if (rst == 1) Q_int <= 16'd0; else if (Load == 1) Q_int <= D; else if (Shift == 1) Q_int <= {Sin,Q_int[15:1]}; else Q_int <= Q_int; end endmodule module DualPortBlockRAM512x64 ( WriteAddress, DataIn, WriteEnable, ReadAddress, DataOut, clk ); input [ 8:0] WriteAddress; input [63:0] DataIn; input WriteEnable; input [ 8:0] ReadAddress; output [63:0] DataOut; input clk; parameter LO = 1'b0, HI = 1'b1; reg [63:0] DPRAM[511:0]; reg [8:0] RA; always @ (posedge clk) begin if (WriteEnable == HI) DPRAM[WriteAddress] <= DataIn; RA <= ReadAddress; end assign DataOut = DPRAM[RA]; endmodule /*=========================================================================*/ /*=== From the COUNTERS LIBRARY =========================================*/ /*=========================================================================*/ module Counter12(Q, en, rst, clk); output [11:0] Q; input en, rst, clk; reg [11:0] Q_int; assign Q = (rst == 0)? Q_int : 11'd0; always @(posedge clk) begin if (rst == 1) Q_int <= 11'd0; else if (en == 1) Q_int <= Q_int + 1; else Q_int <= Q_int; end endmodule /*=========================================================================*/ /* Programmable Pulse Pattern Generator NOTE: This is NOT an arbitrary pattern generator. Scale : This is a clock prescaler. The pattern generator logic is only active every Nth master clock if Scale is N. This is the rate at which the pattern generator 'ticks'. Period: The period of the waverform in pattern generator ticks. Rise : The output goes HI 'Rise' ticks after rollover or reset. Fall : The output goes LO 'Fall' ticks after rollover or reset. The pattern generator resets to LO upon an active reset, but remains unchanged upon a rollover. */ /*=========================================================================*/ /* MODULE: PulseGen16 * DESCRIPTION: Programmable Pulse Generator * This module produces a single HI pulse once every 'Period' system clocks. * This range may be arbitrarily extended by gating the 'en' input as only * those clocks that occur while enabled are counted. * * The output is only asserted when the module is enabled. */ module PulseGen8(Q, Period, en, rst, clk); output Q; input [7:0] Period; input en, rst, clk; parameter HI = 1'b1, LO = 1'b0; wire D; reg [7:0] count, newcount; always @(posedge clk) begin count <= newcount; end assign D = (newcount == 8'd0)? HI : LO; DFFRen DFF (.Q(Q), .D(D), .en(HI), .rst(rst), .clk(clk)); always @(count or Period or rst or en) begin if (rst == HI) newcount <= Period; else if (en == 1) if (count == 8'd0) newcount <= Period; else newcount <= count - 1; else begin newcount <= count; end end endmodule module PulseGen16(Q, Period, en, rst, clk); output Q; input [15:0] Period; input en, rst, clk; parameter HI = 1'b1, LO = 1'b0; wire D; reg [15:0] count, newcount; always @(posedge clk) begin count <= newcount; end assign D = (newcount == 16'd0)? HI : LO; DFFRen DFF (.Q(Q), .D(D), .en(HI), .rst(rst), .clk(clk)); always @(count or Period or rst or en) begin if (rst == HI) newcount <= Period; else if (en == 1) if (count == 16'd0) newcount <= Period; else newcount <= count - 1; else begin newcount <= count; end end endmodule module PulseGen24(Q, Period, en, rst, clk); output Q; input [23:0] Period; input en, rst, clk; parameter HI = 1'b1, LO = 1'b0; wire D; reg [23:0] count, newcount; always @(posedge clk) begin count <= newcount; end assign D = (newcount == 24'd0)? HI : LO; DFFRen DFF (.Q(Q), .D(D), .en(HI), .rst(rst), .clk(clk)); always @(count or Period or rst or en) begin if (rst == HI) newcount <= Period; else if (en == 1) if (count == 24'd0) newcount <= Period; else newcount <= count - 1; else begin newcount <= count; end end endmodule module Binary2Gray12(Gray, Binary, rst, clk); output [11:0] Gray; input [11:0] Binary; input rst, clk; assign Gray[11] = Binary[11]; assign Gray[10:0] = Binary[11:1]^Binary[10:0]; endmodule module Gray2Binary12(Binary, Gray, rst, clk); output [11:0] Binary; input [11:0] Gray; input rst, clk; wire [11:0] Binary_int; assign Binary = Binary_int; assign Binary_int[11] = Gray[11]; assign Binary_int[10:0] = Binary_int[11:1]^Gray[10:0]; endmodule /*=========================================================================*/ /*=== From the MUXES LIBRARY ============================================*/ /*=========================================================================*/ module MUX2(Q, D1, D0, Sel); output Q; input D1, D0; input Sel; wire [1:0] D; assign D = {D1,D0}; MUX2TAP MUX (.Q(Q), .D(D), .Sel(Sel)); endmodule module MUX4(Q, D3, D2, D1, D0, Sel); output Q; input D3, D2, D1, D0; input [1:0] Sel; wire [3:0] D; assign D = {D3,D2,D1,D0}; MUX4TAP MUX (.Q(Q), .D(D), .Sel(Sel)); endmodule module MUX2TAP(Q, D, Sel); output Q; input [1:0] D; input Sel; reg Q_int; assign Q = Q_int; always @ (D or Sel) begin case (Sel) 0: Q_int = D[0]; 1: Q_int = D[1]; default : Q_int = 1'd0; endcase end endmodule module MUX4TAP(Q, D, Sel); output Q; input [3:0] D; input [1:0] Sel; reg Q_int; assign Q = Q_int; always @ (D or Sel) begin case (Sel) 0: Q_int = D[0]; 1: Q_int = D[1]; 2: Q_int = D[2]; 3: Q_int = D[3]; default : Q_int = 1'd0; endcase end endmodule module MUX2x2(Q, D1, D0, Sel); output [1:0] Q; input [1:0] D1, D0; input Sel; MUX2 B1 (.Q(Q[1]), .D1(D1[1]), .D0(D0[1]), .Sel(Sel)); MUX2 B0 (.Q(Q[0]), .D1(D1[0]), .D0(D0[0]), .Sel(Sel)); endmodule module MUX2x8(Q, D1, D0, Sel); output [7:0] Q; input [7:0] D1, D0; input Sel; MUX2 B7 (.Q(Q[7]), .D1(D1[7]), .D0(D0[7]), .Sel(Sel)); MUX2 B6 (.Q(Q[6]), .D1(D1[6]), .D0(D0[6]), .Sel(Sel)); MUX2 B5 (.Q(Q[5]), .D1(D1[5]), .D0(D0[5]), .Sel(Sel)); MUX2 B4 (.Q(Q[4]), .D1(D1[4]), .D0(D0[4]), .Sel(Sel)); MUX2 B3 (.Q(Q[3]), .D1(D1[3]), .D0(D0[3]), .Sel(Sel)); MUX2 B2 (.Q(Q[2]), .D1(D1[2]), .D0(D0[2]), .Sel(Sel)); MUX2 B1 (.Q(Q[1]), .D1(D1[1]), .D0(D0[1]), .Sel(Sel)); MUX2 B0 (.Q(Q[0]), .D1(D1[0]), .D0(D0[0]), .Sel(Sel)); endmodule module MUX2x16(Q, D1, D0, Sel); output [15:0] Q; input [15:0] D1, D0; input Sel; MUX2 B15 (.Q(Q[15]), .D1(D1[15]), .D0(D0[15]), .Sel(Sel)); MUX2 B14 (.Q(Q[14]), .D1(D1[14]), .D0(D0[14]), .Sel(Sel)); MUX2 B13 (.Q(Q[13]), .D1(D1[13]), .D0(D0[13]), .Sel(Sel)); MUX2 B12 (.Q(Q[12]), .D1(D1[12]), .D0(D0[12]), .Sel(Sel)); MUX2 B11 (.Q(Q[11]), .D1(D1[11]), .D0(D0[11]), .Sel(Sel)); MUX2 B10 (.Q(Q[10]), .D1(D1[10]), .D0(D0[10]), .Sel(Sel)); MUX2 B9 (.Q(Q[ 9]), .D1(D1[ 9]), .D0(D0[ 9]), .Sel(Sel)); MUX2 B8 (.Q(Q[ 8]), .D1(D1[ 8]), .D0(D0[ 8]), .Sel(Sel)); MUX2 B7 (.Q(Q[ 7]), .D1(D1[ 7]), .D0(D0[ 7]), .Sel(Sel)); MUX2 B6 (.Q(Q[ 6]), .D1(D1[ 6]), .D0(D0[ 6]), .Sel(Sel)); MUX2 B5 (.Q(Q[ 5]), .D1(D1[ 5]), .D0(D0[ 5]), .Sel(Sel)); MUX2 B4 (.Q(Q[ 4]), .D1(D1[ 4]), .D0(D0[ 4]), .Sel(Sel)); MUX2 B3 (.Q(Q[ 3]), .D1(D1[ 3]), .D0(D0[ 3]), .Sel(Sel)); MUX2 B2 (.Q(Q[ 2]), .D1(D1[ 2]), .D0(D0[ 2]), .Sel(Sel)); MUX2 B1 (.Q(Q[ 1]), .D1(D1[ 1]), .D0(D0[ 1]), .Sel(Sel)); MUX2 B0 (.Q(Q[ 0]), .D1(D1[ 0]), .D0(D0[ 0]), .Sel(Sel)); endmodule module MUX4x2(Q, D3, D2, D1, D0, Sel); output [1:0] Q; input [1:0] D3, D2, D1, D0; input [1:0] Sel; MUX4 B1 (.Q(Q[ 1]), .D3(D3[ 1]), .D2(D2[ 1]), .D1(D1[ 1]), .D0(D0[ 1]), .Sel(Sel)); MUX4 B0 (.Q(Q[ 0]), .D3(D3[ 0]), .D2(D2[ 0]), .D1(D1[ 0]), .D0(D0[ 0]), .Sel(Sel)); endmodule module MUX4x8(Q, D3, D2, D1, D0, Sel); output [7:0] Q; input [7:0] D3, D2, D1, D0; input [1:0] Sel; MUX4 B7 (.Q(Q[ 7]), .D3(D3[ 7]), .D2(D2[ 7]), .D1(D1[ 7]), .D0(D0[ 7]), .Sel(Sel)); MUX4 B6 (.Q(Q[ 6]), .D3(D3[ 6]), .D2(D2[ 6]), .D1(D1[ 6]), .D0(D0[ 6]), .Sel(Sel)); MUX4 B5 (.Q(Q[ 5]), .D3(D3[ 5]), .D2(D2[ 5]), .D1(D1[ 5]), .D0(D0[ 5]), .Sel(Sel)); MUX4 B4 (.Q(Q[ 4]), .D3(D3[ 4]), .D2(D2[ 4]), .D1(D1[ 4]), .D0(D0[ 4]), .Sel(Sel)); MUX4 B3 (.Q(Q[ 3]), .D3(D3[ 3]), .D2(D2[ 3]), .D1(D1[ 3]), .D0(D0[ 3]), .Sel(Sel)); MUX4 B2 (.Q(Q[ 2]), .D3(D3[ 2]), .D2(D2[ 2]), .D1(D1[ 2]), .D0(D0[ 2]), .Sel(Sel)); MUX4 B1 (.Q(Q[ 1]), .D3(D3[ 1]), .D2(D2[ 1]), .D1(D1[ 1]), .D0(D0[ 1]), .Sel(Sel)); MUX4 B0 (.Q(Q[ 0]), .D3(D3[ 0]), .D2(D2[ 0]), .D1(D1[ 0]), .D0(D0[ 0]), .Sel(Sel)); endmodule module MUX16x8 ( Q, DF, DE, DD, DC, DB, DA, D9, D8, D7, D6, D5, D4, D3, D2, D1, D0, Sel ); output [7:0] Q; input [7:0] DF, DE, DD, DC, DB, DA, D9, D8; input [7:0] D7, D6, D5, D4, D3, D2, D1, D0; input [3:0] Sel; reg [7:0] Q_int; assign Q = Q_int; always @ ( Sel or DF or DE or DD or DC or DB or DA or D9 or D8 or D7 or D6 or D5 or D4 or D3 or D2 or D1 or D0 ) begin case (Sel) 0: Q_int = D0; 1: Q_int = D1; 2: Q_int = D2; 3: Q_int = D3; 4: Q_int = D4; 5: Q_int = D5; 6: Q_int = D6; 7: Q_int = D7; 8: Q_int = D8; 9: Q_int = D9; 10: Q_int = DA; 11: Q_int = DB; 12: Q_int = DC; 13: Q_int = DD; 14: Q_int = DE; 15: Q_int = DF; default : Q_int = 8'd0; endcase end endmodule /*=========================================================================*/ /*=== From the FIFOS LIBRARY ============================================*/ /*=========================================================================*/ module FIFO16x8(DataOut, DataIn, FF, AF, HF, AE, EF, Push, Pop, Dump, Clk); parameter WIDTH = 8; parameter DEPTH = 16; parameter LOG2DEPTH = 4; input [(WIDTH-1):0] DataIn; output [(WIDTH-1):0] DataOut; output FF, AF, HF, AE, EF; input Push, Pop, Dump, Clk; wire WE, RE; reg [(LOG2DEPTH-1):0] Contents, ReadPointer, WritePointer; reg [(WIDTH-1):0] queue[(DEPTH-1):0]; assign FF = (Contents == (DEPTH-1))? 1 : 0; assign AF = (Contents > (DEPTH-3))? 1 : 0; assign HF = (Contents > (DEPTH/2))? 1 : 0; assign AE = (Contents < 3)? 1 : 0; assign EF = (Contents == 0)? 1 : 0; assign WE = Push && ~FF; assign RE = Pop && ~EF; assign DataOut = queue[ReadPointer]; always @ (posedge Clk) begin if (Dump == 1) Contents <= 0; else if ((WE == 1) && (RE == 0)) Contents <= Contents + 1; else if ((WE == 0) && (RE == 1)) Contents <= Contents - 1; else Contents <= Contents; end always @ (posedge Clk) begin if (Dump == 1) begin ReadPointer <= 0; WritePointer <= 0; end else begin if (RE == 1) begin ReadPointer <= ReadPointer + 1; end if (WE == 1) begin queue[WritePointer] <= DataIn; WritePointer <= WritePointer + 1; end end end endmodule module FIFO16x24(DataOut, DataIn, FF, AF, HF, AE, EF, Push, Pop, Dump, Clk); parameter WIDTH = 24; parameter DEPTH = 16; parameter LOG2DEPTH = 4; input [(WIDTH-1):0] DataIn; output [(WIDTH-1):0] DataOut; output FF, AF, HF, AE, EF; input Push, Pop, Dump, Clk; wire WE, RE; reg [(LOG2DEPTH-1):0] Contents, ReadPointer, WritePointer; reg [(WIDTH-1):0] queue[(DEPTH-1):0]; assign FF = (Contents == (DEPTH-1))? 1 : 0; assign AF = (Contents > (DEPTH-3))? 1 : 0; assign HF = (Contents > (DEPTH/2))? 1 : 0; assign AE = (Contents < 3)? 1 : 0; assign EF = (Contents == 0)? 1 : 0; assign WE = Push && ~FF; assign RE = Pop && ~EF; assign DataOut = queue[ReadPointer]; always @ (posedge Clk) begin if (Dump == 1) Contents <= 0; else if ((WE == 1) && (RE == 0)) Contents <= Contents + 1; else if ((WE == 0) && (RE == 1)) Contents <= Contents - 1; else Contents <= Contents; end always @ (posedge Clk) begin if (Dump == 1) begin ReadPointer <= 0; WritePointer <= 0; end else begin if (RE == 1) begin ReadPointer <= ReadPointer + 1; end if (WE == 1) begin queue[WritePointer] <= DataIn; WritePointer <= WritePointer + 1; end end end endmodule module FIFO16x32(DataOut, DataIn, FF, AF, HF, AE, EF, Push, Pop, Dump, Clk); parameter WIDTH = 32; parameter DEPTH = 16; parameter LOG2DEPTH = 4; input [(WIDTH-1):0] DataIn; output [(WIDTH-1):0] DataOut; output FF, AF, HF, AE, EF; input Push, Pop, Dump, Clk; wire WE, RE; reg [(LOG2DEPTH-1):0] Contents, ReadPointer, WritePointer; reg [(WIDTH-1):0] queue[(DEPTH-1):0]; assign FF = (Contents == (DEPTH-1))? 1 : 0; assign AF = (Contents > (DEPTH-3))? 1 : 0; assign HF = (Contents > (DEPTH/2))? 1 : 0; assign AE = (Contents < 3)? 1 : 0; assign EF = (Contents == 0)? 1 : 0; assign WE = Push && ~FF; assign RE = Pop && ~EF; assign DataOut = queue[ReadPointer]; always @ (posedge Clk) begin if (Dump == 1) Contents <= 0; else if ((WE == 1) && (RE == 0)) Contents <= Contents + 1; else if ((WE == 0) && (RE == 1)) Contents <= Contents - 1; else Contents <= Contents; end always @ (posedge Clk) begin if (Dump == 1) begin ReadPointer <= 0; WritePointer <= 0; end else begin if (RE == 1) begin ReadPointer <= ReadPointer + 1; end if (WE == 1) begin queue[WritePointer] <= DataIn; WritePointer <= WritePointer + 1; end end end endmodule /* * MODULE: PacketBuffer16() * * This module is a FIFO with and additional wrapper to keep track of packets * in the buffer. The packet can be anything and it is the responsibility of * the Pushing and Popping entitities to determine when a packet has been * pushed and when it has been popped - generally via some artifact of the * packet itself such as a terminating NULL. */ module PacketBuffer16(DataOut, DataIn, PacketIn, PacketOut, Lines, FF, AF, HF, AE, EF, Push, Pop, Dump, Clk); parameter WIDTH = 8; parameter DEPTH = 16; parameter LOG2DEPTH = 4; input [(WIDTH-1):0] DataIn; output [(WIDTH-1):0] DataOut; input PacketIn, PacketOut; output [(LOG2DEPTH-1):0] Lines; output FF, AF, HF, AE, EF; input Push, Pop, Dump, Clk; reg [(LOG2DEPTH-1):0] Lines; FIFO16x8 FIFO ( .DataOut(DataOut), .DataIn(DataIn), .FF(FF), .AF(AF), .HF(HF), .AE(AE), .EF(EF), .Push(Push), .Pop(Pop), .Dump(Dump), .Clk(Clk) ); always @ (posedge Clk) begin if (Dump == 1) Lines <= 0; else if ((PacketIn == 1) && (PacketOut == 0)) Lines <= Lines + 1; else if ((PacketIn == 0) && (PacketOut == 1)) Lines <= Lines - 1; else Lines <= Lines; end endmodule /*=========================================================================*/ /*=== From the MMV LIBRARY ==============================================*/ /*=========================================================================*/ /* MODULE: OneShot * This module asserts an output based on two inputs as follows: * STATE: Q0 - Quiescent (output is LO), waiting for Start signal to deassert. * Q1 - Armed (output is LO), waiting for Start signal to assert. * Q2 - Triggered (output is HI), waiting for Stop signal to assert. * Q3 - Stopped (output is LO), waiting for Stop signal to deassert. * * This circuit behaves similarly to a nonretriggerable monostable * multivibrator. * * 1) In order to Trigger, the machine MUST be in the armed state. In order * to get into that state, the trigger signal that started the previous * cycle must be relaxed. * * 2) Once triggered, the output will remain asserted until the Stop signal is * asserted, at which point the machine will stop and deassert its output. * * 3) The Stop signal must be deasserted in order for the machine to move back * into the quiescent state. * * The main application of this module is to detect events and create a HI * output pulse that is just long enough to catch a single master clock pulse * while preventing multiple triggers due to long asserted signals. In order * to achieve this behavior it is only necessary to use the Q output as the * Stop input * */ module OneShot(Q, Start, Stop, rst, clk); output Q; input Start, Stop; input rst, clk; reg [1:0] cstate, nstate; reg Q; parameter LO = 1'b0, HI = 1'b1, QUIESCENT = {LO,LO}, ARMED = {LO,HI}, RUNNING = {HI,LO}, STOPPED = {HI,HI}; always @ (posedge clk) begin if (rst == HI) cstate <= STOPPED; else cstate <= nstate; end always @ (cstate or Start or Stop) begin case (cstate) QUIESCENT: begin Q <= LO; if (Start == LO) nstate <= ARMED; else nstate <= QUIESCENT; end ARMED: begin Q <= LO; if (Start == HI) nstate <= RUNNING; else nstate <= ARMED; end RUNNING: begin Q <= HI; if (Stop == HI) nstate <= STOPPED; else nstate <= RUNNING; end STOPPED: begin Q <= LO; if (Stop == LO) nstate <= QUIESCENT; else nstate <= STOPPED; end default: begin Q <= LO; nstate <= STOPPED; end endcase end endmodule module FireAndAcknowledge(Q, Fire, Ack, rst, clk); output Q; input Fire, Ack; input rst, clk; reg Q; parameter LO = 1'b0, HI = 1'b1; reg [1:0] State, Next_State; reg Q_next; parameter S_IDLE = 2'd0, S_ARMED = 2'd1, S_FIRED = 2'd2; always @ (posedge clk) begin if (rst == HI) begin Q <= LO; State <= S_IDLE; end else begin Q <= Q_next; State <= Next_State; end end // FSM State Transition Definitions always @ (State or Fire or Ack) begin case (State) S_IDLE: // Hold until Fire flag is relaxed begin Q_next = LO; if (Fire == LO) begin Next_State = S_ARMED; end else begin Next_State = State; end end S_ARMED: // Waiting for Fire flag begin if (Fire == HI) begin Q_next = HI; Next_State = S_FIRED; end else begin Q_next = LO; Next_State = State; end end S_FIRED: // Hold Output HI until acknowledged begin if (Ack == HI) begin Q_next = LO; Next_State = S_IDLE; end else begin Q_next = HI; Next_State = State; end end default: begin Q_next = LO; Next_State = S_IDLE; end endcase end endmodule /*=========================================================================*/ /*=== END OF LIBRARY ====================================================*/ /*=========================================================================*/