blob: 430c72c26490768be284cc3931906eee67dcf734 [file] [log] [blame]
// $Id: $
// File name: timer.sv
// Created: 11/28/2020
// Author: Zachary Ellis
// Lab Section: 337-08
// Version: 2.0 Remove dumb timer logic
// Description: timing block for CAN reciever
module timer (
input clk,
input nRST,
input [3:0] TS1,
input [3:0] TS2,
input edgedet,
input bitstuff,
input dataphase,
input [3:0] pkt_size,
output reg bitstrobe,
output reg tx_strobe,
output reg byte_complete,
output [3:0] byte_num,
output end_data
);
typedef enum logic [1:0] {
SYNC,
PROP,
PHASE1,
PHASE2
} timer_state_t;
timer_state_t state, next_state;
reg [3:0] count, next_count;
reg next_bitstrobe;
always_ff @(posedge clk, negedge nRST) begin
if(nRST == 1'b0) begin
state <= SYNC;
count <= '0; //this is better for hardware and doesn't really affect function
end
else begin
state <= next_state;
count <= next_count;
end
end
always_comb begin
next_state = state;
next_count = count + 1;
bitstrobe = 1'b0;
tx_strobe = 1'b0;
case(state)
SYNC: begin
tx_strobe = 1'b1;
next_state = PROP;
end
PROP: begin
if(edgedet) next_state = PROP;
else next_state = PHASE1;
end
PHASE1: begin
if(edgedet) next_state = PROP;
else if(count == TS1) next_state = PHASE2;
end
PHASE2: begin
if(count == 1 && ~edgedet) bitstrobe = 1'b1; //weird edge case
if(edgedet) begin
next_state = PROP;
tx_strobe = 1'b1;
end
else if(count == TS2) next_state = SYNC;
end
endcase
if(next_state != state) next_count = 1;
end
wire [3:0] byte_numraw;
assign byte_num = (byte_numraw) ? byte_numraw - 4'd1 : 4'd0;
flex_counter #(
.NUM_CNT_BITS(4)
)
BYTETIMER(
.clk(bitstrobe),
.n_rst(nRST),
.clear(!dataphase),
.count_enable(~bitstuff),
.rollover_val(4'd8),
.count_out(),
.rollover_flag(byte_complete)
);
flex_counter #(
.NUM_CNT_BITS(4)
)
PAYLOADTIMER(
.clk(byte_complete),
.n_rst(dataphase),
.clear(1'b0),
.count_enable(1'b1),
.rollover_val(pkt_size),
.count_out(byte_numraw),
.rollover_flag(end_data)
);
endmodule