module dec #(m = 32) ( //clock and reset input logic clk, clrn, //control slave input logic ctl_wr, ctl_rd, input logic ctl_addr, input logic [31:0] ctl_wrdata, output logic [31:0] ctl_rddata, //memory slave input logic ram_wr, input logic [3:0] ram_addr, input logic [31:0] ram_wrdata, //external ports input logic train, output logic red, yellow, green ); typedef enum logic [1:0] {RED, YELLOW, BLINK, GREEN} FSMStates; logic run; logic [1:0] divider; logic [1:0] state; logic [31:0] greenSaved; logic [31:0] greenCount; logic [m-1:0] divisor; logic [1:0] contr; logic [2:0] colors; logic [m-1:0] cntdiv; logic enacnt; //control slave logic always_ff @ (posedge clk or negedge clrn) begin if (!clrn) begin run <= 0; divider <= 0; end else begin if (ctl_wr) begin case (ctl_addr) 1'b0: run <= ctl_wrdata[0]; 1'b1: divider <= ctl_wrdata[1:0]; endcase end end end always_comb begin case (ctl_addr) 1'b0: ctl_rddata = {31'b0,run}; 1'b1: ctl_rddata = {30'b0,divider}; default: ctl_rddata = 'bx; endcase end //semaphore logic always_ff @ (posedge clk or negedge clrn) begin if (!clrn) cntdiv <= 0; else begin if (train | ~run) cntdiv<=0; else begin if (enacnt) cntdiv<=0; else cntdiv<=cntdiv+1; end end end // we don't enable counters, if color is green always_comb begin enacnt = ((cntdiv == divisor) && !(colors == 3'b001)); end always_ff @ (posedge clk or negedge clrn) begin if (!clrn) begin colors <= 3'b001; state <= GREEN; greenCount <= 32'd0; end else begin if (~run) begin colors <= 3'b001; state <= GREEN; end if (train) begin colors <= 3'b100; state <= RED; greenSaved <= divisor; greenCount <= divisor; end else begin case (state) RED: begin colors <= 3'b100; if (enacnt) begin state <= YELLOW; greenSaved <= divisor; end end YELLOW: begin colors <= 3'b010; if (enacnt) begin state <= BLINK; end end BLINK: begin if (enacnt) begin state <= GREEN; end if (greenSaved[0] == 0) begin colors <= 3'b011; end else begin greenCount <= greenCount - 1'b1; if (greenCount == 32'd0) begin colors[1] <= ~colors[1]; greenCount <= greenSaved; end end end GREEN: begin colors <= 3'b001; end default: colors <= 3'b100; endcase end end end assign contr = state; // always_comb begin // case (state) // 2'b00: contr = 2'b00; // 2'b01: contr = 2'b01; // 2'b10: contr = 2'b10; // 2'b11: contr = 2'b11; // default : contr = 2'b00; // endcase // end assign red = colors[2]; assign yellow = colors[1]; assign green = colors[0]; periodram b2v_inst3 ( .clock(clk), .data (ram_wrdata), .wraddress (ram_addr), .wren (ram_wr), .rdaddress({divider,contr}), .q(divisor) ); endmodule