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
依照題目描述實作 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
題目描述較長,但核心是簡化版 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