/*=================================================================*/ /*=== Loop Controller ===========================================*/ /*=================================================================*/ /* * FILE: LoopController.v * PROGRAMMER: William L. Bahn * * CONTENTS: * * NAMING CONVENTION: */ // LoopController Control Register Map // | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | // | RUN | LOAD | INI | N/A | A[3] | A[2] | A[1] | A[0] | module LoopController ( Test, Time, CR, Data, IP, IP_Load, rst, clk ); output [ 7:0] Test; // Test Signal Bus output [15:0] Time; input [ 7:0] CR; // Control Register input [15:0] Data; // Control Register Data output [15:0] IP; output IP_Load; input rst, clk; parameter LO = 1'b0, HI = 1'b1; wire Loop_RUN; wire Loop_LOAD; wire Loop_INI; wire [ 3:0] Loop_CRA; wire [15:0] Loop_CRD; assign Loop_RUN = CR[7]; assign Loop_LOAD = CR[6]; assign Loop_INI = CR[5]; assign Loop_CRA = CR[3:0]; assign Loop_CRD = Data; // ------------------------------------------------------------ // Memory Manager // ------------------------------------------------------------ wire [ 3:0] memWA; wire [15:0] memWD; assign memWS = Loop_LOAD; assign memWA = Loop_CRA; assign memWD = Loop_CRD; reg [15:0] Memory[15:0]; always @ (posedge clk) begin if (memWS == HI) Memory[memWA] <= memWD; else Memory[memWA] <= Memory[memWA]; end // ------------------------------------------------------------ // Register Map // ------------------------------------------------------------ wire [15:0] IL_cycles, ML_cycles, OL_cycles; // Loop Cycle wire [15:0] IL_vector, ML_vector, OL_vector; // Loop Vectors wire [15:0] IL_length, ML_length, OL_length; // Loop Length assign IL_vector = Memory[4'h0]; assign IL_length = Memory[4'h1]; assign IL_cycles = Memory[4'h2]; assign ML_vector = Memory[4'h4]; assign ML_length = Memory[4'h5]; assign ML_cycles = Memory[4'h6]; assign OL_vector = Memory[4'h8]; assign OL_length = Memory[4'h9]; assign OL_cycles = Memory[4'hA]; // Timer Controller reg TimerRst_int; wire TimerRst; assign TimerRst = ((Loop_INI==HI)||(TimerRst_int==HI))? HI:LO; reg [15:0] Timer; always @ (posedge clk) begin if (TimerRst == HI) Timer <= 0; else Timer <= Timer + 1; end assign Time = Timer; reg [15:0] IL_count, ML_count, OL_count; // Cycle Counters reg [15:0] IL_count_int, ML_count_int, OL_count_int; always @ (posedge clk) begin OL_count <= OL_count_int; ML_count <= ML_count_int; IL_count <= IL_count_int; end reg [15:0] IP_int; reg [15:0] Vector; reg VectorLoad; always @ (posedge clk) begin if (VectorLoad == 1) IP_int <= Vector; else IP_int <= IP_int; end assign IP = IP_int; assign IP_Load = VectorLoad; parameter S_INI = 4'd0, S_IL_RUN = 4'd1, S_ML_RUN = 4'd2, S_OL_RUN = 4'd3, S_TRAP = 4'd15; reg [3:0] State, Next_State; always @ (posedge clk) begin if (rst == 1) State <= S_INI; else State <= Next_State; end always @ ( State or Timer or Loop_INI or Loop_RUN or IP_int or OL_vector or OL_cycles or OL_length or OL_count or ML_vector or ML_cycles or ML_length or ML_count or IL_vector or IL_cycles or IL_length or IL_count ) begin case (State) S_INI: begin OL_count_int = OL_cycles; ML_count_int = ML_cycles; IL_count_int = IL_cycles; TimerRst_int = HI; if ((Loop_INI == HI)||(Loop_RUN == LO)) begin Vector = IP_int; VectorLoad = LO; Next_State = State; end else begin Vector = OL_vector; VectorLoad = HI; Next_State = S_OL_RUN; end end S_OL_RUN: begin OL_count_int = OL_count; ML_count_int = ML_count; IL_count_int = IL_count; if ((Loop_INI == HI)||(Loop_RUN == LO)) begin TimerRst_int = HI; Vector = IP_int; VectorLoad = LO; Next_State = S_INI; end else if (OL_length == Timer) begin TimerRst_int = HI; Vector = ML_vector; VectorLoad = HI; Next_State = S_ML_RUN; end else begin Vector = IP_int; VectorLoad = LO; Next_State = State; TimerRst_int = LO; end end S_ML_RUN: begin OL_count_int = OL_count; ML_count_int = ML_count; IL_count_int = IL_count; if ((Loop_INI == HI)||(Loop_RUN == LO)) begin Vector = IP_int; VectorLoad = LO; TimerRst_int = HI; Next_State = S_INI; end else if (ML_length == Timer) begin TimerRst_int = HI; Vector = IL_vector; VectorLoad = HI; Next_State = S_IL_RUN; end else begin Vector = IP_int; VectorLoad = LO; Next_State = State; TimerRst_int = LO; end end S_IL_RUN: begin if ((Loop_INI == HI)||(Loop_RUN == LO)) begin OL_count_int = OL_count; ML_count_int = ML_count; IL_count_int = IL_count; Vector = IP_int; VectorLoad = LO; TimerRst_int = HI; Next_State = S_INI; end else if (IL_length == Timer) begin TimerRst_int = HI; if (IL_count != 0) begin OL_count_int = OL_count; ML_count_int = ML_count; IL_count_int = IL_count - 1; Vector = IL_vector; VectorLoad = HI; Next_State = S_IL_RUN; end else if (ML_count != 0) begin OL_count_int = OL_count; ML_count_int = ML_count - 1; IL_count_int = IL_cycles; Vector = ML_vector; VectorLoad = HI; Next_State = S_ML_RUN; end else if (OL_count != 0) begin OL_count_int = OL_count - 1; ML_count_int = ML_cycles; IL_count_int = IL_cycles; Vector = OL_vector; VectorLoad = HI; Next_State = S_OL_RUN; end else begin OL_count_int = OL_cycles; ML_count_int = ML_cycles; IL_count_int = IL_cycles; Vector = OL_vector; VectorLoad = HI; Next_State = S_INI; end end else begin TimerRst_int = LO; OL_count_int = OL_count; ML_count_int = ML_count; IL_count_int = IL_count; Vector = IL_vector; VectorLoad = LO; Next_State = State; end end default: begin OL_count_int = OL_count; ML_count_int = ML_count; IL_count_int = IL_count; TimerRst_int = HI; Vector = OL_vector; VectorLoad = LO; Next_State = S_INI; end endcase end assign Test = {State, IL_count[3:0]}; endmodule