URL
https://opencores.org/ocsvn/instruction_list_pipelined_processor_with_peripherals/instruction_list_pipelined_processor_with_peripherals/trunk
Subversion Repositories instruction_list_pipelined_processor_with_peripherals
Compare Revisions
- This comparison shows the changes necessary to convert path
/instruction_list_pipelined_processor_with_peripherals/trunk
- from Rev 1 to Rev 2
- ↔ Reverse comparison
Rev 1 → Rev 2
/ramBit.v
0,0 → 1,54
|
`include "timescale.v" |
`include "defines.v" |
|
module bitRam (clk, reset, bitRamEn, bitRamRw, bitRamIn, bitRamAddr, bitRamOut); |
|
|
input clk, reset, bitRamEn, bitRamRw, bitRamIn; |
input [`bitRamAddrLen-1:0] bitRamAddr; |
|
output bitRamOut; |
|
reg bitRam [`bitRamDepth-1:0]; |
reg bitRamOut; |
|
|
always @ (posedge clk or posedge reset) |
begin |
|
if (reset) |
begin |
bitRamOut = 1'b0; |
$write (" module bitRam is reset "); |
end |
|
else |
begin |
|
if (bitRamEn) |
begin |
if (bitRamRw) // read operation |
begin |
bitRamOut = bitRam[bitRamAddr]; |
$write (" reading bit-RAM : module bitRAM "); |
end |
|
else // write operation |
begin |
bitRam[bitRamAddr] = bitRamIn; |
$write (" writing to bit-RAM : module bitRam "); |
end |
end |
|
else |
begin |
bitRamOut = 1'bZ; |
end |
|
end // end else of reset |
|
end // end always block |
|
|
endmodule |
/tcAccum.v
0,0 → 1,45
|
`include "timescale.v" |
`include "defines.v" |
|
|
module tcAccum (tcAccumRead, tcAddr, tcAccumIn, tcAccumOut); |
|
input tcAccumRead; |
input [`tcAddrLen-1:0] tcAddr; |
input [(`tcAccLen*`tcNumbers)-1:0] tcAccumIn; |
|
output [`tcAccLen-1:0] tcAccumOut; |
|
wire [`tcAccLen-1:0] ACC_all [`tcNumbers-1:0]; // used in continuous assignment |
reg [`tcAccLen-1:0] tcAccumOut; |
|
|
always @ (tcAccumRead or tcAddr) |
begin |
if (tcAccumRead) |
begin |
tcAccumOut = ACC_all[tcAddr]; |
$write (" reading t/c accumulated value : module tcAccum "); |
end |
end |
|
assign ACC_all[0] = tcAccumIn[`tcAccLen-1:0]; |
assign ACC_all[1] = tcAccumIn[(`tcAccLen*2)-1:`tcAccLen]; |
assign ACC_all[2] = tcAccumIn[(`tcAccLen*3)-1:(`tcAccLen*2)]; |
assign ACC_all[3] = tcAccumIn[(`tcAccLen*4)-1:(`tcAccLen*3)]; |
assign ACC_all[4] = tcAccumIn[(`tcAccLen*5)-1:(`tcAccLen*4)]; |
assign ACC_all[5] = tcAccumIn[(`tcAccLen*6)-1:(`tcAccLen*5)]; |
assign ACC_all[6] = tcAccumIn[(`tcAccLen*7)-1:(`tcAccLen*6)]; |
assign ACC_all[7] = tcAccumIn[(`tcAccLen*8)-1:(`tcAccLen*7)]; |
assign ACC_all[8] = tcAccumIn[(`tcAccLen*9)-1:(`tcAccLen*8)]; |
assign ACC_all[9] = tcAccumIn[(`tcAccLen*10)-1:(`tcAccLen*9)]; |
assign ACC_all[10] = tcAccumIn[(`tcAccLen*11)-1:(`tcAccLen*10)]; |
assign ACC_all[11] = tcAccumIn[(`tcAccLen*12)-1:(`tcAccLen*11)]; |
assign ACC_all[12] = tcAccumIn[(`tcAccLen*13)-1:(`tcAccLen*12)]; |
assign ACC_all[13] = tcAccumIn[(`tcAccLen*14)-1:(`tcAccLen*13)]; |
assign ACC_all[14] = tcAccumIn[(`tcAccLen*15)-1:(`tcAccLen*14)]; |
assign ACC_all[15] = tcAccumIn[(`tcAccLen*16)-1:(`tcAccLen*15)]; |
|
|
endmodule |
/uartFifo.v
0,0 → 1,145
|
`include "timescale.v" |
`include "defines.v" |
|
|
module uartFifo(clk, reset, wData, rData, wr, rd, full, empty); |
|
parameter dataBits = `dataBits; |
parameter fifoWidth = `fifoWidth; |
parameter fiforegs = `number_fifo_regs; |
parameter fifoCntrWidth = `fifoCntrWidth; |
parameter fifodepth = `fifoDepth; |
|
// integer i; |
|
input [dataBits-1 : 0] wData; |
input clk, reset, rd, wr; |
output [`dataBits-1 : 0] rData; |
output full, empty; |
|
reg [dataBits-1 : 0] fifoReg [0:fiforegs-1]; |
|
reg [dataBits-1 : 0] rData; |
|
reg full=1'b0, empty=1'b1; |
|
// pointers |
reg [fifoWidth-1 : 0] top = 4'b1111, bottom = 4'b1111; |
wire [fifoWidth-1 : 0] topPlusOne = top + 1'b1; |
|
//counter |
reg [fifoCntrWidth-1 : 0] cntr = 0; |
|
|
always @ (posedge clk or posedge reset) |
begin |
|
if (reset) |
begin |
top = 0; |
bottom = 0; |
|
fifoReg[0] = 0; |
fifoReg[1] = 0; |
fifoReg[2] = 0; |
fifoReg[3] = 0; |
fifoReg[4] = 0; |
fifoReg[5] = 0; |
fifoReg[6] = 0; |
fifoReg[7] = 0; |
fifoReg[8] = 0; |
fifoReg[9] = 0; |
fifoReg[10] = 0; |
fifoReg[11] = 0; |
fifoReg[12] = 0; |
fifoReg[13] = 0; |
fifoReg[14] = 0; |
fifoReg[15] = 0; |
end //end if(reset) |
|
|
|
else |
begin |
|
case ({rd, wr}) |
|
2'b 01 : if (cntr <= fifodepth) |
begin |
fifoReg[top] = wData; |
top = topPlusOne; |
cntr = cntr + 1'b1; |
end |
|
2'b 10 : if (cntr > 0) |
begin |
rData = fifoReg[bottom]; |
fifoReg[bottom] = 0; |
bottom = bottom + 1'b1; |
cntr = cntr - 1'b1; |
|
end |
|
2'b 11 : if ((cntr >0) & (cntr <= fifodepth)) |
begin |
rData = fifoReg[bottom]; |
fifoReg[bottom] = 0; |
bottom = bottom + 1'b1; |
fifoReg[top] = wData; |
top = topPlusOne; |
end |
|
default : ; |
endcase |
|
end // end else |
|
end // end always |
|
//assign rData = fifoReg[bottom]; |
|
always @ (posedge clk or posedge reset) |
begin |
|
if (reset) |
begin |
full <= 1'b0; |
empty <= 1'b1; end |
|
else |
begin |
if(~rd & (cntr>=(fifodepth-1))) |
begin |
full <= 1'b1; |
//$display ($time, " ns \t * FIFO FULL "); |
empty <= 1'b0; end |
|
else if (~wr & (cntr==4'b0000)) |
begin |
empty <= 1'b1; |
full <= 1'b0; end |
|
else if ((cntr != 0) | (cntr != fifodepth)) |
begin |
empty <= 1'b0; |
full <= 1'b0; end |
end // end else i.e. (!reset) |
|
end // end always |
|
|
always @ * |
begin |
|
if (full & wr) |
$display ($time, "ns \t\t attempting to write to full fifo.... data overwritten"); |
|
else |
if (empty & rd) |
$display ($time, "ns \t\t attempting to read from empty fifo..."); |
|
end |
|
|
endmodule |
/controlUnit.v
0,0 → 1,55
|
`include "timescale.v" |
`include "defines.v" |
|
|
module controlUnit (clk, reset, instOpCodeIn, acc0, iomemCode, |
branch, |
accMuxSel, accEn, op2MuxSel, aluOpcode, |
bitRamEn, bitRamRw, byteRamEn, byteRamRw, |
inputRead, outputRw |
|
`ifdef timerAndCounter_peripheral |
, entypeEn, tcAccRead, tcResetEn, tcPresetEn, tcLoadEn |
`endif |
|
`ifdef UART_peripheral |
, uartRead, uartWrite |
`endif |
|
`ifdef SPI_peripheral |
, sconEn, spiStatRead, spiBufRead, spiBufWrite, spiBufShift |
`endif |
|
); |
|
|
input clk, reset; |
input [`instOpCodeLen-1:0] instOpCode; |
input acc0; |
input [1:0] iomemCode; |
|
output branch; |
output [`accMuxSelLen-1:0] accMuxSel; |
output accEn; |
output [`op2MuxSelLen-1:0] op2MuxSel; |
output [`aluOpcodeLen-1:0] aluOpcode; |
output bitRamEn, bitRamRw, byteRamEn, byteRamRw; |
output inputRead, outputRw; |
|
`ifdef timerAndCounter_peripheral |
output entypeEn, tcAccRead, tcResetEn, tcPresetEn, tcLoadEn; |
`endif; |
|
`ifdef UART_peripheral |
output uartRead, uartWrite; |
`endif |
|
`ifdef SPI_peripheral |
output sconEn, spiStatRead, spiBufRead, spiBufWrite, spiBufShift; |
`endif |
|
|
|
|
endmodule |
/spiEngine.v
0,0 → 1,105
|
`include "timescale.v" |
`include "defines.v" |
|
|
module spiEngine (in8, out8, clk, s_in, s_out, sclk, bufMe, EN, Sh, BF); |
|
|
input s_in, EN, clk, Sh, bufMe; |
input [7:0] in8; |
|
output s_out, sclk, BF; |
output [7:0] out8; |
|
reg s_out, sclk, BF=1'b0; |
reg [7:0] sbuf = 8'b 00000000, out8 = 8'b 00000000; |
|
integer i = 4'b 0000; |
|
parameter data_width = 8; |
|
parameter ready = 3'b 000, sch = 3'b 001, scl = 3'b 010, fnsh = 3'b 011;// set-clock-high, set-clock-low, finish (states for shifting) |
reg [2:0] state = ready; |
reg [2:0] nxtCycle; |
|
|
always @ (posedge clk or posedge bufMe) |
begin |
|
if (bufMe) |
sbuf <= in8; |
|
else |
if (Sh && EN) |
|
case (state) |
|
ready : begin |
sclk <= 1'b z; |
s_out <= 1'b z; |
nxtCycle <= sch; |
state <= scl; |
end |
|
sch : begin |
sclk <= 1'b 1; // set SCLK |
|
|
if (i > data_width) begin |
s_out <= 1'b z; |
sclk <= 1'b z; // stop out-ing the SPI clock |
BF <= 1'b 1; |
out8 <= sbuf; |
|
state <= fnsh; // next state should be fnsh after sclk=0 since 1-byte Xfer is done |
end |
|
if (i <= data_width) begin |
sbuf[0] <= s_in; // receive MSB from MASTER_IN pin |
sbuf <= sbuf << 1; // shift SBUF reg content |
BF <= 1'b 0; |
|
nxtCycle <= sch; // next state should be sch after sclk=0 to Xfer remaining bits |
|
state <= scl; |
end |
end |
scl : begin |
sclk <= 1'b 0; // SPI clock goes low |
s_out <= sbuf[data_width - 1]; // send MSB over MASTER_OUT pin |
i <= i+1; |
state <= nxtCycle; // go to either sch or fnsh state (depending upon 'i') |
end |
|
|
fnsh : begin |
BF <= 1'b 1; // raise the buffer-full flag |
i <= 0; // reset counter |
sclk <= 1'b z; // stop out-ing the SPI clock |
s_out <= 1'b z; // stop sending data over MO |
|
// state = ready; //*** |
end |
|
|
default : begin |
BF <= 1'b 0; |
end |
endcase |
|
|
else |
if (!Sh || !EN) |
begin |
state <= ready; |
sclk <= 1'b z; |
s_out <= 1'b z; |
BF <= 1'b 0; |
i <= 0; |
end |
|
end |
|
|
endmodule |
/byteNegator.v
0,0 → 1,29
|
`include "timescale.v" |
`include "defines.v" |
|
module byteNegator (byteIn, byteN, byteOut); |
|
input [7:0] byteIn; |
input byteN; |
|
output [7:0] byteOut; |
|
reg [7:0] byteOut; |
|
|
always @ (byteIn or byteN) |
begin |
|
if (byteN) |
begin |
byteOut = ~ byteIn; |
end |
else |
begin |
byteOut = byteIn; |
end |
|
end |
|
endmodule |
/uartTrans.v
0,0 → 1,140
|
`include "timescale.v" |
`include "defines.v" |
|
|
module uartTrans (clk, reset, sTick, txDoneTick, din, tx, txStart); |
|
parameter dataBits = `dataBits; |
parameter sbTick = `sbTick; |
|
input [dataBits-1 :0] din; |
input clk, reset, sTick, txStart; |
output tx, txDoneTick; |
|
reg txDoneTick; |
|
/* |
should be impleneted as a 4-state FSM : idle, start, data, stop; |
|
*/ |
|
localparam [1:0] idle = 2'b00, start = 2'b01, data = 2'b10, stop = 2'b11; |
|
reg [1:0] stateReg, stateNext; // current and next states |
reg [3:0] sReg, sNext; // counter |
reg [2:0] nReg, nNext; // counter |
reg [7:0] bReg, bNext; // perhaps keeps data to be sent |
reg txReg, txNext; // current bit being transferred |
|
|
// reset and non-reset conditions: |
|
always @ (posedge clk or posedge reset) |
begin |
if (reset) |
begin |
stateReg <= idle; |
sReg <= 1'b0; |
bReg <= 1'b0; |
nReg <= 1'b0; |
txReg <= 1'b1; |
end // end if |
|
else |
begin |
stateReg <= stateNext; |
sReg <= sNext; |
bReg <= bNext; |
nReg <= nNext; |
txReg <= txNext; |
end // end else |
|
end // end always |
|
// FSM: |
|
always @ * |
begin |
stateNext = stateReg; |
sNext = sReg; |
bNext = bReg; |
nNext = nReg; |
txNext = txReg; |
|
txDoneTick = 1'b0; // not done yet! |
|
case (stateReg) |
|
idle : begin |
txNext = 1'b1; // start bit '0'; thus, send '1' in idle |
|
if (txStart) |
begin |
txDoneTick = 1'b1; // generate rd for fifo ** |
stateNext = start; // should go into start state |
sNext = 0; |
end // end if txStart |
// in idle state unless txStart... |
end // end idle case |
|
start : begin |
txNext = 0; |
txDoneTick = 1'b0; // ** |
bNext = din; // take din into bReg |
if (sTick) |
if (sReg == 15) |
begin |
stateNext = data; |
sNext = 1'b0; |
nNext = 1'b0; |
end // end if sReg==15 |
|
else |
sNext = sReg + 1; // keep incrementing sNext (sReg) |
// sReg = sNext on each clk edge !! |
end // end start case |
|
data : begin |
txNext = bReg[0]; // keep sending LSB of bReg |
|
if (sTick) |
if (sReg == 15) |
begin |
sNext = 0; // reset counter |
bNext = bReg >> 1; // shift word to be sent |
|
if (nReg == (dataBits-1)) |
stateNext = stop; |
else |
nNext = nReg +1; |
end // end if sReg==15 |
else |
sNext = sReg + 1; |
|
end // end data state |
|
stop : begin |
txNext = 1'b1; |
|
if (sTick) |
if (sReg == sbTick-1) |
begin |
stateNext = idle; |
//txDoneTick = 1'b1; it's working as read signal to |
// fifo, so, used at starting . . . |
end //end if sReg==15 |
else |
sNext = sReg + 1; |
end // end stop state |
|
endcase |
|
end // end always combinatorial |
|
|
// output bit-stream |
|
assign tx = txReg; |
|
endmodule |
/spiStatReg.v
0,0 → 1,22
|
`include "timescale.v" |
`include "defines.v" |
|
|
module spiStatReg (spiStatIn, spiStatRead, spiStatOut); |
|
input spiStatRead; |
input [7:0] spiStatIn; |
|
output [7:0] spiStatOut; |
|
reg [7:0] spiStatOut, status = 8'b 00000000; |
|
always @ (spiStatRead or status) |
if (spiStatRead) |
spiStatOut = status; |
|
always @ (spiStatIn) |
status = spiStatIn; |
|
endmodule |
/spiBufReg.v
0,0 → 1,27
|
`include "timescale.v" |
`include "defines.v" |
|
|
module spiBufReg(Rd, in8, bufOUT); |
|
input Rd; |
input [7:0] in8; |
|
output [7:0] bufOUT; |
|
|
reg [7:0] bufOUT, BUFFER = 8'b 00000000; |
|
|
always @ (Rd) |
|
bufOUT = BUFFER; |
|
|
always @ (in8) |
BUFFER = in8; |
|
|
|
endmodule |
/bitNegator.v
0,0 → 1,27
|
`include "timescale.v" |
`include "defines.v" |
|
module bitNegator (bitIn, bitN, bitOut); |
|
input bitIn, bitN; |
output bitOut; |
|
reg bitOut; |
|
|
always @ (bitIn or bitN) |
begin |
|
if (bitN) |
begin |
bitOut = ~ bitIn; |
end |
else |
begin |
bitOut = bitIn; |
end |
|
end |
|
endmodule |
/top.v
0,0 → 1,172
`include "timescale.v" |
`include "defines.v" |
|
module top(clk, reset, IN, OUT |
|
`ifdef UART_peripheral |
, rx, tx |
`endif |
|
`ifdef SPI_peripheral |
, MISO, MOSI, SCK |
`endif |
|
); |
|
|
|
input clk,reset; |
input [`inputNumber-1:0] IN; |
output [`outputNumber-1:0] OUT; |
|
`ifdef UART_peripheral |
input rx; |
output tx; |
`endif |
|
`ifdef SPI_peripheral |
input MISO; |
output MOSI, SCK; |
`endif |
|
// wires (interconnects) of execution unit |
|
wire [`instLen-1:0] pcOut; |
wire [`instOpCodeLen-1:0] instOpCode; |
wire [`instFieldLen-1:0] instField; |
|
wire [7:0] accMuxOut; |
wire [7:0] accOut; |
wire [7:0] op2MuxOut; |
wire [7:0] aluOut; |
|
wire bitNegatorRamOut, bitOut; |
wire [7:0] byteNegatorRamOut, byteOut; |
|
wire inputReadOut, outputReadOut; |
|
// wires (interconnects) of timer & counter |
|
`ifdef timerAndCounter_peripheral |
|
`endif |
|
|
|
//-------- Fetch Unit Module Instances |
// all necessary |
|
pgmCounter ProgramCounter (); |
|
instReg IntructionRegister (); |
|
|
// instruction ROM is declared using xilinx primitive |
RAMB16_S18 rom ( .DI(), |
.DIP(), |
.ADDR(), |
.EN(1'b1), |
.WE(), |
.SSR(1'b0), |
.CLK(), |
.DO(), |
.DOP()); |
|
|
|
//-------- Execute Unit Modules Instances |
// all necessary |
|
|
|
|
accumulatorMUX accMUX1 (); |
|
accumulator acc (); |
|
byteNegator byteNegatorForOp2Mux (); |
|
op2Mux op2MUX1 (); |
|
alu arithLogicUnit (); |
|
bitNegator bitNegatorForBitRam (); |
|
bitRam RAM_Bit (); |
|
byteNegator byteNegatorForByteRam (); |
|
byteRam RAM_Byte (); |
|
inputRegister inputStorage (); |
|
outputReg outputStorage (); |
|
|
//---------- Timer & Counter Modules |
// optional |
|
`ifdef timerAndCounter_peripheral |
|
tcEnableAndType tcEnableAndTypeModule(); |
|
tcAccum tcAccumModule(); |
|
tcReset tcResetModule(); |
|
tcPreset tcPresetModule(); |
|
tcLoad tcLoadModule(); |
|
timer timer0(); |
|
timer timer1(); |
|
timer timer2(); |
|
timer timer3(); |
|
counter counter0(); |
|
counter counter1(); |
|
counter counter2(); |
|
counter counter3(); |
|
`endif |
|
//---------- UART Modules |
// optional |
|
`ifdef UART_peripheral |
|
|
uartTrans UART_TRANSMITTER (); |
|
uartRec UART_RECIEVER (); |
|
uartBrg UART_BitRateGenerator (); |
|
uartFifo UART_TRANS_FIFO (); |
|
uartFifo UART_REC_FIFO (); |
|
`endif |
|
//---------- SPI Modules |
// optional |
|
`ifdef SPI_peripheral |
|
spiStatReg SPI_STATUS_REG (); |
|
spiConReg SPI_CONTROL_REG (); |
|
spiBufReg SPI_BUFFER_REG (); |
|
spiEngine SPI_MAIN (); |
|
`endif |
|
endmodule |
/ramByte.v
0,0 → 1,58
|
`include "timescale.v" |
`include "defines.v" |
|
module byteRam (clk, reset, byteRamEn, byteRamRw, byteRamIn, byteRamAddr, byteRamOut); |
|
input clk, reset, byteRamEn, byteRamRw; |
input [`byteRamLen-1:0] byteRamIn; |
input [`byteRamAddrLen-1:0] byteRamAddr; |
|
output [`byteRamLen-1:0] byteRamOut; |
|
reg [`byteRamLen-1:0] byteRam [`byteRamDepth-1:0]; |
reg [`byteRamLen-1:0] byteRamOut; |
|
|
always @ (posedge clk or posedge reset) |
begin |
|
if (reset) |
begin |
byteRamOut = `byteRamLen'b0; |
$write (" module byteRam is reset "); |
end |
|
else |
begin |
|
if (byteRamEn) |
begin |
|
if (byteRamRw) // read operation |
begin |
byteRamOut = byteRam[byteRamAddr]; |
$write (" reading byte RAM : module byteRam "); |
end |
|
|
else // write operation |
begin |
byteRam[byteRamAddr] = byteRamIn; |
$write (" writing to byte RAM : module byteRam "); |
end |
|
end |
|
else // if Enable = 0 |
begin |
|
byteRamOut = `byteRamLen'bz; |
|
end |
|
end // end else of reset |
|
end // end always |
|
endmodule |
/tcLoad.v
0,0 → 1,33
|
`include "timescale.v" |
`include "defines.v" |
|
|
module tcLoad (tcLoadEn, tcAddr, dnIn, ttIn, cuIn, cdIn, tcLoadOut); |
|
input tcLoadEn; |
input [`tcAddrLen-1:0] tcAddr; |
input [`tcNumbers-1:0] dnIn, ttIn, cuIn, cdIn; |
|
output [7:0] tcLoadOut; |
|
reg [`tcNumbers-1:0] dnInReg, ttInReg, cuInReg, cdInReg; |
|
wire dnSel, ttSel, cuSel, cdSel; |
|
always @ * |
begin |
dnInReg = dnIn; |
ttInReg = ttIn; |
cuInReg = cuIn; |
cdInReg = cdIn; |
end |
|
assign dnSel = dnInReg[tcAddr]; |
assign ttSel = ttInReg[tcAddr]; |
assign cuSel = cuInReg[tcAddr]; |
assign cdSel = cdInReg[tcAddr]; |
|
assign tcLoadOut = {4'b0, dnSel, ttSel, cuSel, cdSel}; |
|
endmodule |
/counter_all.v
0,0 → 1,120
|
`include "timescale.v" |
`include "defines.v" |
|
|
module counter (clk, reset, preset, type, DN, CU, CD, ACC); |
|
input clk, reset; |
input [`tcPresetLen-1:0] preset; |
input [`tcTypeLen-1:0] type; |
|
output DN, CU, CD; |
output [`tcAccLen-1:0] ACC; |
|
reg DN, CU, CD; |
reg [`tcAccLen-1:0] ACC; |
|
reg [`tcTypeLen-1:0] CounterType; |
reg [`tcTypeLen-1:0] typeNext; |
|
|
parameter UpCounter = `tcTypeLen'b01; |
parameter DownCounter = `tcTypeLen'b10; |
parameter defaultType = `tcTypeLen'b00; |
|
|
|
always @ (type) |
begin |
|
case (type) |
|
`counterType1 : begin |
typeNext = UpCounter; |
end |
|
`counterType2 : begin |
typeNext = DownCounter; |
end |
|
default : begin |
$display ("counter is of undefined type.\n Valid types are Up counter & Down counter"); |
end |
endcase |
end |
|
|
always @ (posedge clk or posedge reset) |
begin |
|
if (reset) |
begin |
$display ("counter module is reset"); |
CounterType = defaultType; |
end |
else |
begin |
CounterType = typeNext; |
end |
end |
|
|
always @ (posedge clk) |
begin |
|
case (CounterType) |
|
UpCounter : begin |
CD = 0; // CD id always 0 for this state |
|
if (reset) |
begin |
ACC = `tcAccLen-1'b0; // starts at lowest value |
CU = 0; |
DN = 0; |
end |
else |
begin |
ACC = ACC + 1'b1; |
CU = 1'b1; |
if (ACC > preset) |
begin |
DN = 1'b1; |
end |
end |
end |
|
|
|
DownCounter : begin |
CU = 0; // CU id always 0 for this state |
|
if (reset) |
begin |
ACC = `tcAccLen-1'b1; // starts at highest value |
CD = 0; |
DN = 0; |
end |
else |
begin |
ACC = ACC - 1'b1; |
CD = 1'b1; |
if (ACC < preset) |
begin |
DN = 1'b1; |
end |
end |
end |
|
|
|
default : begin |
$display (" error in counter type "); |
end |
|
endcase |
end |
|
|
endmodule |
/tcReset.v
0,0 → 1,27
|
`include "timescale.v" |
`include "defines.v" |
|
|
module tcReset (tcResetEn, resetIn, tcAddr, resetOut); |
|
input tcResetEn, resetIn; |
input [`tcAddrLen-1:0] tcAddr; |
|
output [`tcNumbers-1:0] resetOut; |
|
reg [`tcNumbers-1:0] resets; |
|
|
always @ * |
begin |
if (tcResetEn) |
begin |
resets[tcAddr] = resetIn; |
end |
end |
|
assign resetOut = resets; |
|
|
endmodule |
/instReg.v
0,0 → 1,30
|
`include "timescale.v" |
`include "defines.v" |
|
|
module instReg (instIn, instOpCode, instField); |
|
input [`instLen:0-1] instIn; |
|
output [`instOpCodeLen-1:0] instOpCode; |
output [`instFieldLen-1:0] instField; |
|
reg [`instLen-1:0] instRegister; |
|
|
always @ (instIn) |
begin |
|
instRegister = instIn; |
|
end |
|
|
assign instOpcode = instRegister[`instLen-1:(`instLen-`instOpCodeLen)]; |
|
assign instField = instRegister[(`instFieldLen-1):0]; |
|
|
|
endmodule |
/defines.v
0,0 → 1,95
// 16-bit process controller defines |
|
`define immDataLen 8 |
|
// program counter & instruction register |
`define instLen 15 // 15-bit fixed-length instructions |
`define instOpCodeLen 5 |
`define instFieldLen 10 |
|
// alu opcodes |
`define aluOpcodeLen 4 |
`define AND_alu `aluOpcodeLen'b0 |
`define OR_alu `aluOpcodeLen'b1 |
`define XOR_alu `aluOpcodeLen'b10 |
`define GT_alu `aluOpcodeLen'b11 |
`define GE_alu `aluOpcodeLen'b100 |
`define EQ_alu `aluOpcodeLen'b101 |
`define LE_alu `aluOpcodeLen'b110 |
`define LT_alu `aluOpcodeLen'b111 |
`define ADD_alu `aluOpcodeLen'b1000 |
`define SUB_alu `aluOpcodeLen'b1001 |
`define MUL_alu `aluOpcodeLen'b1010 |
`define DIV_alu `aluOpcodeLen'b1011 |
|
|
// bit RAM |
`define bitRamAddrLen 7 // 7-bit address |
`define bitRamDepth 128 // 2^7 = 128 locations |
|
// byte RAM |
`define byteRamLen 8 // 8-bit input |
`define byteRamAddrLen 7 // 7-bit address |
`define byteRamDepth 128 // 2^7 = 128 locations |
|
// input register |
`define inputNumber 128 // 128 inputs |
`define inputAddrLen 7 // 7-bit address |
|
// output register |
`define outputNumber 128 // 128 outputs |
`define outputAddrLen 7 // 7-bit address |
|
// accumulator multiplexer |
`define accMuxSelLen 4 // 2^4 = 16 selections available for accumulator |
`define accMuxSel0 `accMuxSelLen'b0 |
`define accMuxSel1 `accMuxSelLen'b1 |
`define accMuxSel2 `accMuxSelLen'b10 |
`define accMuxSel3 `accMuxSelLen'b11 |
`define accMuxSel4 `accMuxSelLen'b100 |
`define accMuxSel5 `accMuxSelLen'b101 |
|
// operand2 multiplexer |
`define op2MuxSelLen 4 // 2^4 = 16 selections available for op2 |
`define op2MuxSel0 `op2MuxSelLen'b0 |
`define op2MuxSel1 `op2MuxSelLen'b1 |
`define op2MuxSel2 `op2MuxSelLen'b10 |
`define op2MuxSel3 `op2MuxSelLen'b11 |
`define op2MuxSel4 `op2MuxSelLen'b100 |
`define op2MuxSel5 `op2MuxSelLen'b101 |
`define op2MuxSel6 `op2MuxSelLen'b110 |
|
//----------------------------------------------------------------------------------------------------- |
|
// peripheral defines |
`define timerAndCounter_peripheral |
`define UART_peripheral |
`define SPI_peripheral |
|
|
//----------------------------------------------------------------------------------------------------- |
|
// Timer-Counter |
`define tcAccLen 8 // 8-bit accumulated value |
`define tcPresetLen 8 // 8-bit preset value |
`define tcAddrLen 4 |
`define tcTypeLen 2 // max 4-types |
`define tcNumbers 16 // total 16 modules (8-timers, 8-counters) |
|
`define timerType1 `tcTypeLen'b0 |
`define timerType2 `tcTypeLen'b1 |
`define timerType3 `tcTypeLen'b10 |
|
`define counterType1 `tcTypeLen'b1 |
`define counterType2 `tcTypeLen'b10 |
|
|
//----------------------------------------------------------------------------------------------------- |
|
// UART |
`define dataBits 8 |
`define sbTick 16 // ticks for stop bits (16 for 1-stopBit) |
`define fifoWidth 4 |
`define number_fifo_regs 16 |
`define fifoCntrWidth 5 |
`define fifoDepth 16 |
/accumulator.v
0,0 → 1,29
|
`include "timescale.v" |
`include "defines.v" |
|
|
module accumulator (accIn, accEn, accOut); |
|
input [7:0] accIn; |
input accEn; |
|
output [7:0] accOut; |
|
reg [7:0] accOut; |
|
always @ (accIn, accEn) |
begin |
if (accEn) |
begin |
accOut = accIn; |
$write (" %b data written to accumulator : module accumulator ", accIn); |
end |
else |
begin |
accOut = accOut; |
end |
end // end always |
|
|
endmodule |
/accMUX.v
0,0 → 1,39
|
`include "timescale.v" |
`include "defines.v" |
|
|
module accumulatorMUX (accMuxSel, immData, aluOut, accMuxOut); |
|
input [`accMuxSelLen-1:0] accMuxSel; |
input [`immDataLen-1:0] immData; |
input [7:0] aluOut; |
|
output [7:0] accMuxOut; |
|
reg [7:0] accMuxOut; |
|
|
always @ * |
begin |
|
case (accMuxSel) |
|
`accMuxSel0 : begin |
accMuxOut = immData; |
end |
|
`accMuxSel1 : begin |
accMuxOut = aluOut; |
end |
|
default : begin |
accMuxOut = 8'bzzzzzzzz; |
end |
|
endcase |
|
end |
|
|
endmodule |
/alu.v
0,0 → 1,78
|
`include "timescale.v" |
`include "defines.v" |
|
module alu (input [`aluOpcodeLen-1:0] aluOpcode, input [7:0] op1, input [7:0] op2, |
output [7:0] aluOut, output carryOut); |
|
|
wire [8:0] operand1 = {1'b0, op1}; |
wire [8:0] operand2 = {1'b0, op2}; |
|
wire [8:0] addRes = operand1 + operand2; |
wire [8:0] subRes = operand1 - operand2; |
|
reg [8:0] aluOutput; |
reg carryOutput; |
|
always @ (op1 or op2 or aluOpcode) |
begin |
|
|
|
case (aluOpcode) |
|
`AND_alu : begin |
aluOutput = op1 & op2; |
end |
|
`OR_alu : begin |
aluOutput = op1 | op2; |
end |
|
`XOR_alu : begin |
aluOutput = op1^op2; |
end |
|
`GT_alu : begin |
aluOutput = op1>op2 ? 1'b1 : 1'b0; |
end |
|
`GE_alu : begin |
aluOutput = op1>=op2 ? 1'b1 : 1'b0; |
end |
|
`EQ_alu : begin |
aluOutput = op1==op2 ? 1'b1 : 1'b0; |
end |
|
`LE_alu : begin |
aluOutput = op1<=op2 ? 1'b1 : 1'b0; |
end |
|
`LT_alu : begin |
aluOutput = op1<op2 ? 1'b1 : 1'b0; |
end |
|
`ADD_alu : begin |
aluOutput = addRes[7:0]; |
carryOutput = addRes[8]; |
end |
|
`SUB_alu : begin |
aluOutput = subRes[7:0]; |
carryOutput = subRes[8]; |
end |
|
default : begin |
aluOutput = 16'b0; |
$write ("Unknown operation. \nmodule : ALU"); |
end |
endcase |
|
end |
|
assign aluOut = aluOutput; |
assign carryOut = carryOutput; |
|
endmodule |
/uartBrg.vhd
0,0 → 1,49
library IEEE; |
use IEEE.STD_LOGIC_1164.ALL; |
use IEEE.math_real.all; |
use ieee.std_logic_unsigned.all; |
|
entity uartBrg is |
generic ( |
DIVISOR: natural := 32000000/(16*9600) -- DIVISOR = 100,000,000 / (16 x BAUD_RATE) |
-- 2400 -> 2604 |
-- 9600 -> 651 |
-- 115200 -> 54 |
-- 1562500 -> 4 |
-- 2083333 -> 3 |
); |
port ( |
clk: in std_logic; -- clock |
reset: in std_logic; -- reset |
outp : out std_logic |
); |
end uartBrg; |
|
architecture Behavioral of uartBrg is |
|
constant COUNTER_BITS : natural := integer(ceil(log2(real(DIVISOR)))); |
signal sample: std_logic; -- 1 clk spike at 16x baud rate |
signal sample_counter: std_logic_vector(COUNTER_BITS-1 downto 0) := (others=> '0'); -- should fit values in 0..DIVISOR-1 |
|
begin |
|
-- sample signal at 16x baud rate, 1 CLK spikes |
sample_process: process (clk,reset) is |
begin |
if reset = '1' then |
sample_counter <= (others => '0'); |
sample <= '0'; |
elsif rising_edge(clk) then |
if sample_counter = DIVISOR-1 then |
sample <= '1'; |
sample_counter <= (others => '0'); |
else |
sample <= '0'; |
sample_counter <= sample_counter + 1; |
end if; |
end if; |
end process; |
|
outp <= sample; |
|
end Behavioral; |
/pgmCounter.v
0,0 → 1,43
|
`include "timescale.v" |
`include "defines.v" |
|
|
module pgmCounter (clk, reset, branch, pcIn, pcOut); |
|
input clk, reset, branch; |
input [`instLen-1:0] pcIn; |
|
output [`instLen-1:0] pcOut; |
|
reg [`instLen-1:0] pc = `instLen'b0; |
|
always @ (posedge clk or posedge reset) |
begin |
|
if (reset) |
begin |
pc = `instLen'b0; |
$write (" program counter module is reset. Starting at address 00h "); |
end |
|
else |
begin |
|
if(branch) |
begin |
pc = pcIn; |
$write (" branching at address %h", pcIn); |
end |
else |
begin |
pc = pc + 1'b1; |
end |
end |
end // end always |
|
|
assign pcOut = pc; |
|
|
endmodule |
/spiConReg.v
0,0 → 1,29
|
`include "timescale.v" |
`include "defines.v" |
|
|
module spiConReg (sconEn, sconIn, sconOut); |
|
input sconEn; |
input [7:0] sconIn; |
|
output [7:0] sconOut; |
|
reg [7:0] sconOut, controlBits = 8'b 00000000; |
|
|
always @ (sconEn or controlBits) |
begin |
|
if (sconEn) |
sconOut = controlBits; |
|
end |
|
always @ (sconIn) |
begin |
controlBits = sconIn; |
end |
|
endmodule |
/tcPreset.v
0,0 → 1,43
|
`include "timescale.v" |
`include "defines.v" |
|
|
module tcPreset (tcPresetEn, presetIn, tcAddr, presetOut); |
|
input tcPresetEn; |
input [`tcPresetLen-1:0] presetIn; |
input [`tcAddrLen-1:0] tcAddr; |
|
output [(`tcPresetLen*`tcNumbers)-1:0] presetOut; |
|
reg [`tcPresetLen-1:0] presets [`tcNumbers-1:0]; |
|
|
always @ * |
begin |
if (tcPresetEn) |
begin |
presets[tcAddr] = presetIn; |
end |
end |
|
assign presetOut[`tcPresetLen-1:0] = presets[0]; |
assign presetOut[(`tcPresetLen*2)-1:`tcPresetLen] = presets[1]; |
assign presetOut[(`tcPresetLen*3)-1:(`tcPresetLen*2)] = presets[2]; |
assign presetOut[(`tcPresetLen*4)-1:(`tcPresetLen*3)] = presets[3]; |
assign presetOut[(`tcPresetLen*5)-1:(`tcPresetLen*4)] = presets[4]; |
assign presetOut[(`tcPresetLen*6)-1:(`tcPresetLen*5)] = presets[5]; |
assign presetOut[(`tcPresetLen*7)-1:(`tcPresetLen*6)] = presets[6]; |
assign presetOut[(`tcPresetLen*8)-1:(`tcPresetLen*7)] = presets[7]; |
assign presetOut[(`tcPresetLen*9)-1:(`tcPresetLen*8)] = presets[8]; |
assign presetOut[(`tcPresetLen*10)-1:(`tcPresetLen*9)] = presets[9]; |
assign presetOut[(`tcPresetLen*11)-1:(`tcPresetLen*10)] = presets[10]; |
assign presetOut[(`tcPresetLen*12)-1:(`tcPresetLen*11)] = presets[11]; |
assign presetOut[(`tcPresetLen*13)-1:(`tcPresetLen*12)] = presets[12]; |
assign presetOut[(`tcPresetLen*14)-1:(`tcPresetLen*13)] = presets[13]; |
assign presetOut[(`tcPresetLen*15)-1:(`tcPresetLen*14)] = presets[14]; |
assign presetOut[(`tcPresetLen*16)-1:(`tcPresetLen*15)] = presets[15]; |
|
|
endmodule |
/op2Mux.v
0,0 → 1,48
|
`include "timescale.v" |
`include "defines.v" |
|
|
module op2Mux (op2MuxSel, inputReadOut, outputReadOut, bitOut, byteOut, op2MuxOut); |
|
input [`op2MuxSelLen-1:0] op2MuxSel; |
input inputReadOut, outputReadOut, bitOut; |
input [7:0] byteOut; |
|
output [7:0] op2MuxOut; |
|
reg [7:0] op2MuxOut; |
|
|
always @ * |
begin |
|
case (op2MuxSel) |
|
`op2MuxSel0 : begin |
op2MuxOut = {7'b0, inputReadOut}; |
end |
|
`op2MuxSel1 : begin |
op2MuxOut = {7'b0, outputReadOut}; |
end |
|
`op2MuxSel2 : begin |
op2MuxOut = {7'b0, bitOut}; |
end |
|
`op2MuxSel3 : begin |
op2MuxOut = byteOut; |
end |
|
|
default : begin |
op2MuxOut = 8'bzzzzzzzz; |
end |
|
endcase |
|
end // end always |
|
|
endmodule |
/onDelayTimer.v
0,0 → 1,99
|
`include "timescale.v" |
`include "defines.v" |
|
|
module onDelayTimer (reset, en, clk1, clk2, tb, preset, DN, TT, ACC); |
|
input reset, en, clk1, clk2, tb; |
input [`timerPresetLen-1:0] preset; |
|
output DN, TT; |
output [`timerAccLen-1:0] ACC; |
|
reg DN, TT; |
reg [`timerAccLen-1:0] ACC; |
|
|
reg clk; |
|
|
always @ (tb or clk1 or clk2) |
begin |
if (tb) |
begin |
clk = clk1; |
$write (" on-delay timer running on timer-base1 "); |
end |
else |
begin |
clk = clk2; |
$write (" on-delay timer running on timer-base2 "); |
end |
end // end always |
|
|
always @ (posedge clk or posedge reset) // for ACC |
begin |
|
if (reset) |
begin |
ACC = `timerAccLen'b0; |
$write (" on-delay timer is reset "); |
end |
else |
begin |
if (en) |
begin |
if ((ACC < preset)) |
begin |
ACC = ACC + 1'b1; |
end |
else |
begin |
ACC = ACC; |
end |
end |
else |
begin |
ACC = `timerAccLen'b0; |
end |
end |
|
end // end always for ACC |
|
|
always @ (reset or en or ACC or preset) // for DN, TT |
begin |
|
if (reset) |
begin |
DN = 1'b0; |
TT = 1'b0; |
end |
else |
begin |
if (en) |
begin |
if (ACC < preset) |
begin |
DN = 1'b0; |
TT = 1'b1; |
end |
else |
begin |
DN = 1'b1; |
TT = 1'b0; |
end |
end |
else |
begin |
DN = 1'b0; |
TT = 1'b0; |
end |
end |
|
end // end always for DN, TT |
|
|
endmodule |
/inputReg.v
0,0 → 1,44
|
`include "timescale.v" |
`include "defines.v" |
|
|
|
module inputRegister (reset, inputs, inputRead, inputReadAddr, inputReadOut); |
|
input [`inputNumber-1:0] inputs; |
input inputRead, reset; |
input [`inputAddrLen-1:0] inputReadAddr; |
|
output inputReadOut; |
|
reg inputReadOut; |
reg [`inputNumber-1:0] inputReg; |
|
|
always @ (reset or inputs or inputRead or inputReadAddr) |
begin |
|
if (reset) |
begin |
inputReadOut = 1'bz; |
$write (" module inputRegister is reset "); |
end |
|
else |
begin |
|
inputReg = inputs; |
|
if (inputRead) |
begin |
inputReadOut = inputReg [inputReadAddr]; |
$write (" reading input : module inputRegister "); |
end |
|
end |
|
end |
|
|
endmodule |
/outputReg.v
0,0 → 1,51
|
`include "timescale.v" |
`include "defines.v" |
|
|
module outputReg (reset, outputRw, outputRwAddr, outputWriteIn, outputReadOut, outputs); |
|
input reset, outputRw; |
input [`outputAddrLen-1:0] outputRwAddr; |
input outputWriteIn; |
|
output outputReadOut; |
output [`outputNumber-1:0] outputs; |
|
reg outputReadOut; |
reg [`outputNumber-1:0] outputs; |
reg [`outputNumber-1 :0] outputReg; |
|
|
|
always @ (reset or outputRw or outputRwAddr or outputWriteIn or outputReg) |
begin |
|
if (reset) |
begin |
outputReadOut = 1'bz; |
$write (" module outputRegister is reset "); |
end |
|
else |
begin |
|
outputs = outputReg; |
|
if (outputRw) // read output status |
begin |
outputReadOut = outputReg[outputRwAddr]; |
$write (" reading output register : module outputRegister "); |
end |
else // write operation |
begin |
outputReg[outputRwAddr] = outputWriteIn; |
$write (" writing to the output register : module outputRegister "); |
end |
|
end |
|
end |
|
|
endmodule |
/tcEnableAndType.v
0,0 → 1,49
|
`include "timescale.v" |
`include "defines.v" |
|
|
module tcEnableAndType (entypeEn, enIn, typeIn, tcAddr, enOut, typeOut); |
|
input entypeEn, enIn; |
input [`tcTypeLen-1:0] typeIn; // could be `counterTypeLen |
input [`tcAddrLen-1:0] tcAddr; |
|
output wire [`tcNumbers-1:0] enOut; |
output wire [(`tcNumbers*`tcTypeLen)-1:0] typeOut; |
|
reg enables [`tcNumbers-1:0]; |
reg [`tcTypeLen-1:0] types [`tcNumbers-1:0]; |
|
always @ * |
begin |
if (entypeEn) |
begin |
enables[tcAddr] = enIn; |
types[tcAddr] = typeIn; |
end |
end |
|
// assign outputs . . . |
// can write generic??? |
|
assign enOut[0]= enables[0]; |
assign enOut[1]= enables[1]; |
assign enOut[2]= enables[2]; |
assign enOut[3]= enables[3]; |
assign enOut[4]= enables[4]; |
assign enOut[5]= enables[5]; |
assign enOut[6]= enables[6]; |
assign enOut[7]= enables[7]; |
|
assign typeOut[`tcTypeLen-1:0] = types[0]; |
assign typeOut[(`tcTypeLen*2)-1:`tcTypeLen] = types[1]; |
assign typeOut[(`tcTypeLen*3)-1:(`tcTypeLen*2)] = types[2]; |
assign typeOut[(`tcTypeLen*4)-1:(`tcTypeLen*3)] = types[3]; |
assign typeOut[(`tcTypeLen*5)-1:(`tcTypeLen*4)] = types[4]; |
assign typeOut[(`tcTypeLen*6)-1:(`tcTypeLen*5)] = types[5]; |
assign typeOut[(`tcTypeLen*7)-1:(`tcTypeLen*6)] = types[6]; |
assign typeOut[(`tcTypeLen*8)-1:(`tcTypeLen*7)] = types[7]; |
|
|
endmodule |
/uartRec.v
0,0 → 1,114
|
`include "timescale.v" |
`include "defines.v" |
|
|
module uartRec(clk, reset, sTick, rx, rxDoneTick, dOut); |
|
parameter dataBits = `dataBits; |
parameter sbTick = `sbTick; |
|
input clk, reset, sTick, rx; |
output rxDoneTick; |
output [dataBits-1:0] dOut; |
|
reg rxDoneTick; |
// states: |
|
localparam idle = 2'b00, start = 2'b01, data = 2'b10, stop = 2'b11; |
|
reg [1:0] stateReg, stateNext; // current and next states |
reg [3:0] sReg, sNext; // counter |
reg [2:0] nReg, nNext; // counter |
reg [7:0] bReg, bNext; // data recieved in this.. |
|
|
always @ (posedge clk or posedge reset) |
begin |
if (reset) |
begin |
stateReg <= idle; |
sReg <= 1'b0; |
bReg <= 1'b0; |
nReg <= 1'b0; |
end // end if |
|
else |
begin |
stateReg <= stateNext; |
sReg <= sNext; |
bReg <= bNext; |
nReg <= nNext; |
end // end else |
|
end // end always |
|
|
|
// FSM next state logic: |
|
always @ * |
begin |
|
stateNext = stateReg; |
sNext = sReg; |
bNext = bReg; |
nNext = nReg; |
rxDoneTick = 1'b0; |
|
case (stateReg) |
|
idle : if (~rx) |
begin |
stateNext = start; // start when rx is activated |
sNext = 0; // initialize sampling counter |
end // end if rx |
|
start : if (sTick) |
if (sReg == 7) |
begin |
stateNext = data; // at middle of oversampled start |
// bit, go to data state |
sNext = 0; |
nNext = 0; |
end // end if sReg==7 |
|
else |
sNext = sReg + 1; // otherwise keep increment sReg upto 7 |
|
data : if (sTick) |
if (sReg == 15) // if reached middle of next bit |
begin |
sNext = 0; // reset counter |
bNext = {rx, bReg[7:1]}; // LSB first, and the |
//data recieved in bReg |
if (nReg == (dataBits-1)) // if all data recvd, |
stateNext = stop; // go to stop bit(s) state |
else |
nNext = nReg + 1; |
end // end if sReg==15 |
|
else |
sNext = sReg + 1; // otherwise keep increment sReg upto 15 |
|
stop : if (sTick) |
if (sReg == (sbTick-1)) |
begin |
stateNext = idle; // done reception, go to idle state |
rxDoneTick = 1'b1; // raise done tick! |
end // end if sReg==sbTick-1 |
|
else |
sNext = sReg + 1; // otherwise keep increment sReg |
//upto (sbTick-1) |
endcase |
|
end // end always combinatorial |
|
|
// recvd data output |
|
assign dOut = bReg; |
|
|
endmodule |
/timescale.v
0,0 → 1,114
`timescale 1ns / 1ps |
/timer_all.v
0,0 → 1,197
|
|
|
|
|
|
|
|
`include "timescale.v" |
`include "defines.v" |
|
|
|
module timer (clk, en, reset, type, preset, DN, TT, ACC); |
|
input clk, en, reset; |
input [`tcTypeLen-1:0] type; |
input [`tcPresetLen-1:0] preset; |
|
output DN, TT; |
output [`tcAccLen-1:0] ACC; |
|
reg DN, TT; |
reg [`tcAccLen-1:0] ACC; |
|
reg [`tcTypeLen-1:0] TimerType; |
reg [`tcTypeLen-1:0] typeNext; |
|
|
|
parameter OnDelayTimer = `tcTypeLen'b0; |
parameter OffDelayTimer = `tcTypeLen'b1; |
parameter RetOnDelayTimer = `tcTypeLen'b10; |
parameter defaultType = `tcTypeLen'b11; |
|
always @ (type) |
begin |
case (type) |
|
`timerType1 : begin |
typeNext = OnDelayTimer; |
end |
|
`timerType2 : begin |
typeNext = OffDelayTimer; |
end |
|
`timerType3 : begin |
typeNext = RetOnDelayTimer; |
end |
|
default : begin |
|
$display(" Timer is defined for unknown type.\n Valid types: On-delay, Off-delay, retentive-on-delay"); |
end |
|
endcase |
end |
|
|
always @ (posedge clk or posedge reset) |
begin |
if (reset) |
begin |
$write (" timer module is reset "); |
TimerType = defaultType; |
end |
else |
begin |
TimerType = typeNext; |
end |
end |
|
|
always @ (posedge clk) |
begin |
|
|
case (TimerType) |
|
OnDelayTimer : begin |
if (reset) |
begin |
ACC = `tcAccLen'b0; |
DN = 1'b0; |
TT = 1'b0; |
end |
else |
begin |
if (en) |
begin |
if (ACC < preset) |
begin |
ACC = ACC + 1'b1; |
DN = 1'b0; |
TT = 1'b1; |
end |
else if (ACC >= preset) |
begin |
ACC = ACC; |
|
DN = 1'b1; |
TT = 1'b0; |
end |
end |
else |
begin |
ACC = `tcAccLen'b0; // if not enabled |
DN = 1'b0; |
TT = 1'b0; |
end |
end |
end // end this case |
|
OffDelayTimer : begin // not correct implementation! |
if (reset) |
begin |
ACC = `tcAccLen'b0; |
DN = 1'b0; |
TT = 1'b0; |
end |
else |
begin |
if (!en) |
begin |
if (ACC < preset) |
begin |
ACC = ACC + 1'b1; |
DN = 1'b0; |
TT = 1'b1; |
end |
else if (ACC >= preset) |
begin |
ACC = ACC; |
DN = 1'b1; |
TT = 1'b0; |
end |
end |
else |
begin |
ACC = `tcAccLen'b0; // if not enabled |
DN = 1'b0; |
TT = 1'b0; |
end |
end |
end // end this case |
|
RetOnDelayTimer : begin |
|
if (reset) |
begin |
ACC = `tcAccLen'b0; |
DN = 1'b0; |
TT = 1'b0; |
end |
else |
begin |
if (en) |
begin |
if (ACC < preset) |
begin |
ACC = ACC + 1'b1; |
DN = 1'b0; |
TT = 1'b1; |
end |
else if (ACC >= preset) |
begin |
ACC = ACC; |
DN = 1'b1; |
|
|
|
|
TT = 1'b0; |
end |
end |
else |
begin |
ACC = ACC; // retain ACC |
DN = 1'b0; |
TT = 1'b0; |
end |
end |
end // end this case |
|
|
default : begin |
$display(" Error in timer type "); |
end |
|
endcase |
|
end |
|
|
endmodule |
|