Course pages 2015–16
Advanced Computer Design
Exercise 1 - Cambridge Bluespec Web Tutor
- Begin by learning the Bluespec hardware description language by completing the Cambridge Bluespec Tutor.
- Then work through the Bluespec walk through.
- Finally, simulate on your local Linux box the GCD Server code that you wrote as an exercise in the web tutor. You might like to use the following test bench (or the updated version at the bottom of the page).
package GcdTest; import Gcdserver::*; import GetPut::*; import ClientServer::*; import FIFO::*; module mkGcdTest(Empty); Reg#(UInt#(8)) a <- mkReg(1); Reg#(UInt#(8)) b <- mkReg(1); GcdIfc gcd <- mkGcdServer; FIFO#(Bit#(64)) start_time <- mkSizedFIFO(8); rule testInputs(a<16); $display("%04t: Test input: (%2d,%2d)", $time, a, b); gcd.calculate.request.put(GcdT{a:a, b:b}); Bit#(64) t <- $time; start_time.enq(t); if(b<15) b <= b+1; else begin b <= 1; a <= a+1; end endrule rule testOutputs; Bit#(64) t <- $time; t = t - start_time.first; start_time.deq; $display("%04t:\t\t\t\tTest output: Result %2d \tcycles=%2d", $time, gcd.calculate.response.get(), t/10); endrule endmodule endpackage : GcdTest
Assessment
Demonstrate that you understand your GCD code and were able to simulate it on a Linux machine.
Optional Extra
To find out more about the power of Bluespec, take a look at the ServerFarm example and try instantiating two copies of your GCD server vis:
GCDServerT#(`width) divServ <- mkServerFarm(2,mkGCDServer);
What performance improvements do you see?
Note: mkServerFarm uses higher-order types, i.e. you can pass a function as a variable. Try doing that in Verilog or VHDL!
Alternative test bench
Here is an alternative test bench which forwards the test input to the testOutput rule so that the inputs and outputs can be displayed more neatly together.
package GcdTest; import Gcdserver::*; import GetPut::*; import ClientServer::*; import FIFO::*; typedef struct { UInt#(8) a; UInt#(8) b; Bit#(64) start_time; } TestInputT deriving (Bits,Eq); module mkGcdTest(Empty); Reg#(UInt#(8)) a <- mkReg(1); Reg#(UInt#(8)) b <- mkReg(1); GcdIfc gcd <- mkGcdServer; FIFO#(TestInputT) testIn <- mkSizedFIFO(8); rule testInputs(a<16); gcd.calculate.request.put(GcdT{a:a, b:b}); Bit#(64) t <- $time; testIn.enq(TestInputT{a:a, b:b, start_time:t}); if(b<15) b <= b+1; else begin b <= 1; a <= a+1; end endrule rule testOutputs; Bit#(64) t <- $time; t = t - testIn.first.start_time; $display("%04t: Test input = (%2d,%2d) Output result = %2d cycles taken = %2d", $time, testIn.first.a, testIn.first.b, gcd.calculate.response.get(), t/10); testIn.deq; endrule endmodule endpackage : GcdTest