Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
TheBloodthirster authored Sep 18, 2020
1 parent b4e2b29 commit 4ff3df1
Show file tree
Hide file tree
Showing 50 changed files with 2,679 additions and 0 deletions.
69 changes: 69 additions & 0 deletions 高等计算机系统结构/Lab1/RightShifter.bsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import RightShifterTypes::*;
import Gates::*;

function Bit#(1) multiplexer1(Bit#(1) sel, Bit#(1) a, Bit#(1) b);
// Part 1: Re-implement this function using the gates found in the Gates.bsv file
// return (sel == 0)?a:b;
// 使用与或非门实现这条语句,对return a&~sel | b&sel 即可
let a_out = andGate(a,notGate(sel));
let b_out = andGate(b,sel);
let res = orGate(a_out , b_out);
return res;

endfunction

function Bit#(32) multiplexer32(Bit#(1) sel, Bit#(32) a, Bit#(32) b);
// Part 2: Re-implement this function using static elaboration (for-loop and multiplexer1)
// return (sel == 0)?a:b;
Bit#(32) aggregate = 0;
for(Integer i = 0; i < 32; i = i + 1)
begin
aggregate[i] = multiplexer1(sel, a[i], b[i]);
end
return aggregate;
endfunction

function Bit#(n) multiplexerN(Bit#(1) sel, Bit#(n) a, Bit#(n) b);
// Part 3: Re-implement this function as a polymorphic function using static elaboration
// return (sel == 0)?a:b;
Bit#(n) aggregate = 0;
for(Integer i = 0; i < valueof(n); i = i + 1)
begin
aggregate[i] = multiplexer1(sel, a[i], b[i]);
end
return aggregate;
endfunction

function Bit#(n) copy_frontnum(Bit#(1) sign , Integer num);
Bit#(n) result = 0;
for(Integer i = 0;i < num;i = i+1)
begin
result[i] = sign;
end
return result;
endfunction

module mkRightShifter (RightShifter);
method Bit#(32) shift(ShiftMode mode, Bit#(32) operand, Bit#(5) shamt);
// Parts 4 and 5: Implement this function with the multiplexers you implemented
// pack函数用于将各种Bit数据类型(例如Bool,Int或UInt)转换(或打包)为(Bit#(n))类型。
Bit#(32) result = 0;
Bit#(1) flag = 0;
Bit#(1) sign_bit = operand[31];
// flag用来判断是逻辑还是算数右移,逻辑右移前面补0,算数右移前面补符号位。
if(mode == LogicalRightShift)
begin
flag = 1;
end
// 确定要右移前面要填充的0 OR 1
sign_bit = multiplexerN(flag , operand[31] , 0);
// 按照位置右移
result = multiplexerN( shamt[0] , operand, {sign_bit,operand[31:1]});
result = multiplexerN( shamt[1] , result, {copy_frontnum(sign_bit,2),result[31:2]});
result = multiplexerN( shamt[2] , result, {copy_frontnum(sign_bit,4),result[31:4]});
result = multiplexerN( shamt[3] , result, {copy_frontnum(sign_bit,8),result[31:8]});
result = multiplexerN( shamt[4] , result, {copy_frontnum(sign_bit,16),result[31:16]});

return result;
endmethod
endmodule
72 changes: 72 additions & 0 deletions 高等计算机系统结构/Lab1/TestShifter.bsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import RightShifterTypes::*;
import RightShifter::*;

(* synthesize *)
module mkTests (Empty);
RightShifter logicalShifter <- mkRightShifter;
RightShifter arithmeticShifter <- mkRightShifter;

// there are many ways to write tests. Here is a very simple
// version, just to get you started.

rule test;

let g = multiplexer1(1, 1, 0);
if (g != 0) begin
$display("result is ", g, " but expected 0");
end
else begin
$display("correct!");
end

let c = logicalShifter.shift(LogicalRightShift, 12, 2);
if (c != 3) begin
$display("result is ", c, " but expected 3");
end
else begin
$display("correct!");
end

let b = logicalShifter.shift(LogicalRightShift, 12, 1);
if (b != 6) begin
$display("result is ", b, " but expected 6");
end
else begin
$display("correct!");
end

let a = logicalShifter.shift(LogicalRightShift, 1, 1);
if (a != 0) begin
$display("result is ", a);
end
else begin
$display("correct!");
end

let h = logicalShifter.shift(ArithmeticRightShift, 12, 2);
if (h != 3) begin
$display("result is ", h, " but expected 3");
end
else begin
$display("correct!");
end

let i = logicalShifter.shift(LogicalRightShift, -32, 3);
if (i != 536870908) begin
$display("result is ", i, " but expected 536870908");
end
else begin
$display("correct!");
end

let p = logicalShifter.shift(ArithmeticRightShift, -32, 3);
if (p != -4) begin
$display("result is ", p, " but expected -4");
end
else begin
$display("correct!");
end

$finish(0);
endrule
endmodule
Binary file not shown.
Binary file added 高等计算机系统结构/Lab1/实验结果.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 21 additions & 0 deletions 高等计算机系统结构/Lab1/实验结果.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Compile Link and Simulate the Project...
+ bsc -u -sim -simdir . -bdir . -info-dir . -keep-fires -p %/Prelude:%/Libraries:%/Libraries/BlueNoC -g mkTests TestShifter.bsv
checking package dependencies
compiling ./RightShifter.bsv
compiling TestShifter.bsv
code generation for mkTests starts
Elaborated module file created: mkTests.ba
+ bsc -e mkTests -sim -o ./out -simdir . -p %/Prelude:%/Libraries:%/Libraries/BlueNoC -bdir . -keep-fires
All packages are up to date.
Bluesim object created: ./mkTests.{h,o}
Bluesim object created: ./model_mkTests.{h,o}
+ ./out
Simulation shared library created: out.so
Simulation executable created: ./out
correct!
correct!
correct!
correct!
correct!
correct!
Compile/Link/Simulate finished
139 changes: 139 additions & 0 deletions 高等计算机系统结构/Lab2/RightShifter.bsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import RightShifterTypes::*;
import Gates::*;
import FIFO::*;

// 坑一:Lab1是return (sel == 0)?a:b;这里代码变成return (sel == 1)?a:b这不是坑人?
function Bit#(1) multiplexer1(Bit#(1) sel, Bit#(1) a, Bit#(1) b);
return orGate(andGate(a, notGate(sel)),andGate(b, sel));
endfunction

function Bit#(32) multiplexer32(Bit#(1) sel, Bit#(32) a, Bit#(32) b);
Bit#(32) res_vec = 0;
for (Integer i = 0; i < 32; i = i+1)
begin
res_vec[i] = multiplexer1(sel, a[i], b[i]);
end
return res_vec;
endfunction

function Bit#(n) multiplexerN(Bit#(1) sel, Bit#(n) a, Bit#(n) b);
Bit#(n) res_vec = 0;
for (Integer i = 0; i < valueof(n); i = i+1)
begin
res_vec[i] = multiplexer1(sel, a[i], b[i]);
end
return res_vec;
endfunction

// 上一个Lab1编写的复制函数
function Bit#(n) copy_frontnum(Bit#(1) sign , Integer num);
Bit#(n) result = 0;
for(Integer i = 0;i < num;i = i+1)
begin
result[i] = sign;
end
return result;
endfunction

module mkRightShifterPipelined (RightShifterPipelined);
FIFO#(Bit#(1)) high_num <- mkFIFO();
FIFO#(Bit#(5)) shift_num <- mkFIFO();
FIFO#(Bit#(32)) op_num <- mkFIFO();
FIFO#(Bit#(38)) step_for_shift_1 <- mkFIFO();
FIFO#(Bit#(38)) step_for_shift_2 <- mkFIFO();
FIFO#(Bit#(38)) step_for_shift_4 <- mkFIFO();
FIFO#(Bit#(38)) step_for_shift_8 <- mkFIFO();
FIFO#(Bit#(38)) step_for_shift_16 <- mkFIFO();

// 处理右移1位的规则,让流水线能够分段处理5种位移情况。
rule step1 (True);
Bit#(32) operand = op_num.first();
Bit#(5) shamt = shift_num.first();
Bit#(1) high_bit = high_num.first();

let result = multiplexerN(shamt[0] , operand , {high_bit,operand[31:1]});
// 存储流水线step的结果
step_for_shift_1.enq({high_bit,shamt,result});
high_num.deq();
op_num.deq();
shift_num.deq();

endrule

// 处理右移2位的规则
rule step2 (True);
Bit#(32) result = step_for_shift_1.first()[31:0];
Bit#(5) shamt = step_for_shift_1.first()[36:32];
Bit#(1) high_bit = step_for_shift_1.first()[37];

result = multiplexerN(shamt[1] , result , {copy_frontnum(high_bit,2),result[31:2]});

step_for_shift_2.enq({high_bit,shamt,result});
step_for_shift_1.deq();
endrule

// 处理右移4位的规则
rule step3 (True);
Bit#(32) result = step_for_shift_2.first()[31:0];
Bit#(5) shamt = step_for_shift_2.first()[36:32];
Bit#(1) high_bit = step_for_shift_2.first()[37];

result = multiplexerN(shamt[2] , result , {copy_frontnum(high_bit,4),result[31:4]});

step_for_shift_4.enq({high_bit,shamt,result});
step_for_shift_2.deq();
endrule

// 处理右移8位的规则
rule step4 (True);
Bit#(32) result = step_for_shift_4.first()[31:0];
Bit#(5) shamt = step_for_shift_4.first()[36:32];
Bit#(1) high_bit = step_for_shift_4.first()[37];

result = multiplexerN(shamt[3] , result , {copy_frontnum(high_bit,8),result[31:8]});

step_for_shift_8.enq({high_bit,shamt,result});
step_for_shift_4.deq();
endrule

// 处理右移16位的规则
rule step5 (True);
Bit#(32) result = step_for_shift_8.first()[31:0];
Bit#(5) shamt = step_for_shift_8.first()[36:32];
Bit#(1) high_bit = step_for_shift_8.first()[37];

result = multiplexerN(shamt[4] , result , {copy_frontnum(high_bit,16),result[31:16]});

step_for_shift_16.enq({high_bit,shamt,result});
step_for_shift_8.deq();
endrule


method Action push(ShiftMode mode, Bit#(32) operand, Bit#(5) shamt);
/* Write your code here */
// Action push操作输入右移的类别、右移数字、右移位数
Bit#(1) sign_bit = operand[31];
Bit#(1) flag = 0;
// 按照Lab1的思路进行:逻辑右移补0,算术右移补符号位
if(mode == LogicalRightShift)
begin
flag = 1;
end
sign_bit = multiplexerN(flag , sign_bit , 0);

// 把计算出来的数字和参数入队列
high_num.enq(sign_bit);
op_num.enq(operand);
shift_num.enq(shamt);

endmethod

method ActionValue#(Bit#(32)) pull();
/* Write your code here */
// ActionValue这里返回右移的结果
Bit#(32) result = step_for_shift_16.first()[31:0];
step_for_shift_16.deq();
return result;
endmethod

endmodule
36 changes: 36 additions & 0 deletions 高等计算机系统结构/Lab2/TestShifterPipe.bsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import RightShifterTypes::*;
import RightShifter::*;
import FIFO::*;

(* synthesize *)
module mkTests (Empty);
RightShifterPipelined rsp <- mkRightShifterPipelined;
Reg#(Bit#(32)) tbCounter <- mkReg(0);
FIFO#(Bit#(32)) answerFifo <- mkSizedFIFO(6);

// there are many ways to write tests. Here is a very simple
// version, just to get you started.

rule run;
rsp.push(LogicalRightShift, tbCounter, 1);
answerFifo.enq(tbCounter >> 1);
tbCounter <=tbCounter + 1;
endrule

rule test;

let b <- rsp.pull();
let answer = answerFifo.first();
answerFifo.deq();

if (b != answer) begin
$display("result is ", b, " but expected ", answer);
end
else begin
$display("correct!");
end

if (tbCounter > 13) $finish(0);

endrule
endmodule
36 changes: 36 additions & 0 deletions 高等计算机系统结构/Lab2/TestShifterPipe2.bsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import RightShifterTypes::*;
import RightShifter::*;
import FIFO::*;

(* synthesize *)
module mkTests (Empty);
RightShifterPipelined rsp <- mkRightShifterPipelined;
Reg#(Bit#(32)) tbCounter <- mkReg(0);
FIFO#(Bit#(32)) answerFifo <- mkSizedFIFO(6);

// there are many ways to write tests. Here is a very simple
// version, just to get you started.

rule run;
rsp.push(ArithmeticRightShift, -32, 4);
answerFifo.enq(-2);
tbCounter <=tbCounter + 1;
endrule

rule test;

let b <- rsp.pull();
let answer = answerFifo.first();
answerFifo.deq();

if (b != answer) begin
$display("result is ", b, " but expected ", answer);
end
else begin
$display("correct!");
end

if (tbCounter > 13) $finish(0);

endrule
endmodule
Loading

0 comments on commit 4ff3df1

Please sign in to comment.