跳轉到

CS450

Cs450/timer

原題:Cs450/timer

實作 counter 即可。

Verilog
module top_module(
    input clk, 
    input load, 
    input [9:0] data, 
    output tc
);  
    reg [9:0] counter;
    always@(posedge clk)begin
        if(load) counter <= data;
        else if(counter == 10'd0) counter <= 10'd0;
        else counter <= counter - 1'b1;
    end
    assign tc = (counter == 10'd0);
endmodule

Cs450/counter 2bc

原題:Cs450/counter 2bc

依照題目描述實作 FSM。

Verilog
module top_module(
    input clk,
    input areset,
    input train_valid,
    input train_taken,
    output reg [1:0] state
);
    reg [1:0] next_state;
    parameter SNT = 2'b00;
    parameter WNT = 2'b01;
    parameter WT = 2'b10;
    parameter ST = 2'b11;

    always@(*)begin
        if(train_valid)begin
            case(state)
                SNT: next_state= train_taken? WNT: SNT;
                WNT: next_state= train_taken? WT: SNT;
                WT: next_state= train_taken? ST: WNT;
                ST: next_state= train_taken? ST: WT;
            endcase
        end
        else next_state = state;
    end

    always@(posedge clk, posedge areset)begin
        if(areset) state <= WNT;
        else state <= next_state;
    end
endmodule

Cs450/history shift

原題:Cs450/history shift

題目描述較長,但核心是簡化版 branch predictor。先整理訓練與預測訊號,再實作 history shift。

Verilog
module top_module(
    input clk,
    input areset,

    input predict_valid,
    input predict_taken,
    output reg [31:0] predict_history,

    input train_mispredicted,
    input train_taken,
    input [31:0] train_history
);
    always@(posedge clk, posedge areset)begin
        if(areset) predict_history <= 32'd0;
        else if(train_mispredicted) predict_history <= {train_history[30:0], train_taken};
        else if(predict_valid) predict_history <= {predict_history[30:0], predict_taken};
    end
endmodule

Cs450/gshare

原題:Cs450/gshare

整合前兩題:需要同時處理 history 與 PHT 更新。

Verilog
module top_module(
    input clk,
    input areset,

    input  predict_valid,
    input  [6:0] predict_pc,
    output predict_taken,
    output [6:0] predict_history,

    input train_valid,
    input train_taken,
    input train_mispredicted,
    input [6:0] train_history,
    input [6:0] train_pc
);
    //update PHT
    reg [1:0] PHT [127:0];
    wire [6:0]hash;
    assign hash = train_pc ^ train_history;
    integer i;    
    always@(posedge clk, posedge areset)begin
        if(areset)begin
            for(i=0; i<128; i++)begin
                PHT[i] <= 2'b01;
            end
        end 
        else begin
            if(train_taken & train_valid) PHT[hash] <= (PHT[hash] == 2'b11)? 2'b11: PHT[hash] + 2'b01;
            else if(~train_taken & train_valid) PHT[hash] <= (PHT[hash] == 2'b00)? 2'b00: PHT[hash] - 2'b01;
        end
    end    

    assign predict_taken = PHT[predict_pc ^ predict_history][1];
    //update predict history
    always@(posedge clk, posedge areset)begin
        if(areset) predict_history <= 7'd0;
        else if(train_valid & train_mispredicted) predict_history <= {train_history[5:0], train_taken};
        else if(predict_valid) predict_history <= {predict_history[5:0], predict_taken};
    end

endmodule