Presentation is loading. Please wait.

Presentation is loading. Please wait.

Bluespec Lectures 1 & 2. Contact Information Satnam Singh Web:

Similar presentations


Presentation on theme: "Bluespec Lectures 1 & 2. Contact Information Satnam Singh Web:"— Presentation transcript:

1 Bluespec Lectures 1 & 2

2 Contact Information Satnam Singh Email: satnams@microsoft.comsatnams@microsoft.com Web: http://research.microsoft.com/~satnams http://research.microsoft.com/~satnams Lecture notes and other Bluespec information: http://cas.ee.ic.ac.uk/~ssingh http://cas.ee.ic.ac.uk/~ssingh

3 Objectives What is Bluespec? What is the design flow? What is it interesting or important? How is it different from VHDL/Verilog/SystemC/C-to-gate? What is it good for?

4 Overview Lectures 1 & 2: basics about Bluespec rules and their synthesis; examples. Lectures 3 & 4: Scheduling algorithm for rules; FSM design with Bluespec; Higher-order design with Bluespec

5 FPGAs as Co-Processors XD2000i FPGA in-socket accelerator for Intel FSB XD2000F FPGA in-socket accelerator for AMD socket F XD1000 FPGA co-processor module for socket 940

6 Microsoft High Level Synthesis Projects Kiwi: concurrent C# programs for control-oriented applications [Univ. Cambridge] shape analysis: synthesis of dynamic data structures (C) [MPI and CMU] Accelerator/FPGA: synthesis of data parallel programs in C++ [MSR Redmond]

7 opportunity scientific computing data mining search image processing financial analytics challenge

8 ray of light Handel-C System-C CatapultC Occam Streams-C ROCC SPARK Bluespec Esterel Lola

9 Bluespec Spin-off from MIT Control language based on a collection of “atomic rules”. Expression language based on Haskell type system. Original syntax Haskell based. Current syntax inspired by System Verilog.

10 Using Bluespec bombastic.ee.ic.ac.uk goliath.ee.ic.ac.uk Binary: bsc License: at 27004@ee-fs1.ee.ic.ac.uk (just in case) Website: bluespec.com Many thanks to Sam Bayliss for setup help.

11 Counter.bsv interface Counter_Interface; method int count(); endinterface: Counter_Interface (* synthesize *) module mkCounter (Counter_Interface); Reg#(int) c <- mkReg (0) ; rule increment (c < 10); c <= c + 1 ; $display("count = %d", c) ; endrule method int count () = c ; endmodule:mkCounter

12 Simulatiom $ bsc -sim -u Counter.bsv $ bsc -sim -o mkCounter -e mkCounter mkCounter.ba $./mkCounter –m 10 count = 0 count = 1 count = 2 count = 3 count = 4 count = 5 count = 6 count = 7 count = 8 count = 9

13 Verilog $ bsc -verilog Counter.bsv … Verilog file created: mkCounter.v $ vlib work $ vlog mkCounter.v

14

15 Interface Rules1_Interface; method Action setA (int aV); method Action setB (int bV); method int getX(); method int getY(); endinterface: Rules1_Interface (* synthesize *) module rules1 (Rules1_Interface); Reg#(int) a <- mkRegU ; Reg#(int) b <- mkRegU ; Wire#(int) x <- mkWire ; Wire#(int) y <- mkWire ; rule r1 ; x <= 2 * a ; endrule rule r2 ; y <= 3 * b ; endrule method Action setA (int aV); a <= aV ; endmethod: setA method Action setB (int bV); b <= bV ; endmethod: setB method int getX = x ; method int getY = y ; endmodule:rules1 Rules1_Interface setA setB getX getY convert this method into hardware clk a (din)a (qout) clk b (din)b (qout)

16

17 // // Generated by Bluespec Compiler, version 2008.06.E (build 14395, 2008-06-30) // // On Mon Dec 13 06:26:27 PST 2010 // // Method conflict info: // Method: setA // Conflict-free: setB, getX, getY // Sequenced before (restricted): setA // // Method: setB // Conflict-free: setA, getX, getY // Sequenced before (restricted): setB // // Method: getX // Conflict-free: setA, setB, getX, getY // // Method: getY // Conflict-free: setA, setB, getX, getY // // Ports: // Name I/O size props // RDY_setA O 1 const // RDY_setB O 1 const // getX O 32 // RDY_getX O 1 const // getY O 32 // RDY_getY O 1 const // CLK I 1 clock // RST_N I 1 unused // setA_aV I 32 reg // setB_bV I 32 reg // EN_setA I 1 // EN_setB I 1 // // No combinational paths from inputs to outputs //

18 module rules1(CLK, RST_N, setA_aV, EN_setA, RDY_setA, setB_bV, EN_setB, RDY_setB, getX, RDY_getX, getY, RDY_getY); input CLK; input RST_N; // action method setA input [31 : 0] setA_aV; input EN_setA; output RDY_setA;

19 // action method setB input [31 : 0] setB_bV; input EN_setB; output RDY_setB; // value method getX output [31 : 0] getX; output RDY_getX; // value method getY output [31 : 0] getY; output RDY_getY; // signals for module outputs wire [31 : 0] getX, getY; wire RDY_getX, RDY_getY, RDY_setA, RDY_setB; // register a reg [31 : 0] a; wire [31 : 0] a$D_IN; wire a$EN; // register b reg [31 : 0] b; wire [31 : 0] b$D_IN; wire b$EN;

20 // remaining internal signals wire [63 : 0] _3_MUL_b___d2; // action method setA assign RDY_setA = 1'd1 ; // action method setB assign RDY_setB = 1'd1 ; // value method getX assign getX = { a[30:0], 1'd0 } ; assign RDY_getX = 1'd1 ; // value method getY assign RDY_getY = 1'd1 ; assign getY = _3_MUL_b___d2[31:0] ; // register a assign a$D_IN = setA_aV ; assign a$EN = EN_setA ; // register b assign b$D_IN = setB_bV ; assign b$EN = EN_setB ; // remaining internal signals assign _3_MUL_b___d2 = 32'd3 * b ;

21 always@(posedge CLK) begin if (a$EN) a <= `BSV_ASSIGNMENT_DELAY a$D_IN; if (b$EN) b <= `BSV_ASSIGNMENT_DELAY b$D_IN; end // synopsys translate_off `ifdef BSV_NO_INITIAL_BLOCKS `else // not BSV_NO_INITIAL_BLOCKS initial begin a = 32'hAAAAAAAA; b = 32'hAAAAAAAA; end `endif // BSV_NO_INITIAL_BLOCKS // synopsys translate_on endmodule // rules1

22 (* synthesize *) module rules2 (Empty) ; Reg#(int) x <- mkReg (0) ; rule r1 ; x <= x + 1 ; endrule rule r2 ; x <= x + 2 ; endrule rule monitor ; $display ("x = %d", x) ; endrule endmodule

23 $ bsc -verilog Rules2.bsv Warning: "Rules2.bsv", line 2, column 8: (G0010) Rule "r2" was treated as more urgent than "r1". Conflicts: "r2" cannot fire before "r1": calls to x.write vs. x.read "r1" cannot fire before "r2": calls to x.write vs. x.read Warning: "Rules2.bsv", line 6, column 8: (G0021) According to the generated schedule, rule "r1" can never fire. Verilog file created: rules2.v

24 $./rules2 -m 6 x = 0 x = 2 x = 4 x = 6 x = 8

25 (* synthesize *) module rules3 (Empty) ; Reg#(int) x <- mkReg (0) ; Reg#(Bool) b <- mkReg (False) ; rule toggle ; b <= !b ; endrule rule r1 (b) ; x <= x + 1 ; endrule rule r2 (!b) ; x <= x + 2 ; endrule rule monitor ; $display ("x = %d", x) ; endrule endmodule

26 (* synthesize *) module rules3 (Empty) ; Reg#(int) x <- mkReg (0) ; Reg#(Bool) b <- mkReg (False) ; rule toggle ; b <= !b ; endrule rule r1 (b) ; x <= x + 1 ; endrule rule r2 (!b) ; x <= x + 2 ; endrule rule monitor ; $display ("x = %d", x) ; endrule endmodule

27 $./rules3 -m 8 x = 0 x = 2 x = 3 x = 5 x = 6 x = 8 x = 9

28

29 I2C Bus Control in VHDL

30 package DVI_I2C_Init ; import StmtFSM::*; interface I2C_Interface; (* always_ready, always_enabled *) method ActionValue#(bit) sda_out(); (* always_ready, always_enabled *) method Action sda_in(bit v); (* always_ready, always_enabled *) method ActionValue#(bit) rw(); (* always_ready, always_enabled *) method ActionValue#(bit) scl(); (* always_ready, always_enabled *) method ActionValue#(Bit#(8)) versionID(); endinterface: I2C_Interface

31 (* synthesize *) module chrontel_i2c_init (I2C_Interface); Reg#(bit) sdax <- mkReg(1) ; Reg#(bit) sda_inx <- mkRegU ; Reg#(bit) sclx <- mkReg(1) ; Reg#(bit) rwx <- mkReg(0) ; // init IOBUF to drive SDA pin Reg#(Bool) initDone <- mkReg(False) ; Reg#(Bit#(8)) versionIDx <- mkReg (0) ; FSMServer#(Bit#(8), Bit#(0)) send_byte_fsm <- mkSendByte (sdax, sclx) ; FSMServer#(Bit#(0), Bit#(8)) recv_byte_fsm <- mkRecvByte (sda_inx, sclx, rwx) ; Bit#(7) deviceID = 'h76 ; Bit#(8) versionReg = 'h4A ; // Result should be 10010101 = 'h95

32 let doInit = seq i2c_read (deviceID, versionReg, versionIDx, sdax, sda_inx, sclx, rwx, send_byte_fsm, recv_byte_fsm) ; i2c_write (deviceID, 'h49, 'hc0, sdax, sda_inx, sclx, rwx, send_byte_fsm) ; i2c_write (deviceID, 'h21, 'h09, sdax, sda_inx, sclx, rwx, send_byte_fsm) ; i2c_write (deviceID, 'h1d, 'h46, sdax, sda_inx, sclx, rwx, send_byte_fsm) ; i2c_write (deviceID, 'h36, 'h60, sdax, sda_inx, sclx, rwx, send_byte_fsm) ; i2c_write (deviceID, 'h34, 'h16, sdax, sda_inx, sclx, rwx, send_byte_fsm) ; i2c_write (deviceID, 'h33, 'h08, sdax, sda_inx, sclx, rwx, send_byte_fsm) ; endseq ; let doInitFSM <- mkFSM (doInit) ; rule performInit (!initDone) ; doInitFSM.start ; initDone <= True ; endrule

33 method ActionValue#(bit) sda_out ; return sdax ; endmethod method ActionValue#(bit) rw ; return rwx ; endmethod method Action sda_in (bit v) ; sda_inx <= v ; endmethod method ActionValue#(bit) scl ; return sclx ; endmethod method ActionValue#(Bit#(8)) versionID ; return versionIDx ; endmethod endmodule

34 function Stmt i2c_read (Bit#(7) deviceID, Bit#(8) regToRead, Reg#(Bit#(8)) resultReg, Reg#(bit) sda, Reg#(bit) sda_in, Reg#(bit) scl, Reg#(bit) rw, FSMServer#(Bit#(8), Bit#(0)) send_byte_fsm, FSMServer#(Bit#(0), Bit#(8)) recv_byte_fsm) ; Reg#(Bit#(0)) token = ? ; Stmt i2c_read_statement = seq initial_condition (sda, scl) ; token <- callServer (send_byte_fsm, {deviceID, 0}) ; do_ack (sda, sda_in, scl, rw) ; token <- callServer (send_byte_fsm, regToRead) ; do_ack (sda, sda_in, scl, rw) ; initial_condition (sda, scl) ; token <- callServer (send_byte_fsm, {deviceID, 1}) ; do_ack (sda, sda_in, scl, rw) ; resultReg <- callServer (recv_byte_fsm, ?) ; do_noack (sda, sda_in, scl, rw) ; stop_condition (sda, scl) ; endseq ; return i2c_read_statement ; endfunction

35 function Stmt do_ack (Reg#(bit) sda, Reg#(bit) sda_in, Reg#(bit) scl, Reg#(bit) rw) = seq action rw <= 1 ; // Set SDA pin for input scl <= 0 ; //Pulse SCL sda <= 1 ; endaction scl <= 1 ; // Wait for SDA input to drop to zero await (sda_in == 0) ; scl <= 0 ; rw <= 0 ; // Set SDA pin for output endseq; function Stmt do_noack (Reg#(bit) sda, Reg#(bit) sda_in, Reg#(bit) scl, Reg#(bit) rw) = seq action rw <= 1 ; // Set SDA pin for input scl <= 0 ; //Pulse SCL sda <= 1 ; endaction scl <= 1 ; scl <= 0 ; rw <= 0 ; // Set SDA pin for output endseq;

36 interface DVI_Colour_Bars_Interface; (* always_ready, always_enabled *) method ActionValue#(Bit#(10)) vga_r(); (* always_ready, always_enabled *) method ActionValue#(Bit#(10)) vga_g(); (* always_ready, always_enabled *) method ActionValue#(Bit#(10)) vga_b(); (* always_ready, always_enabled *) method ActionValue#(bit) vga_hs(); (* always_ready, always_enabled *) method ActionValue#(bit) vga_vs(); (* always_ready, always_enabled *) method ActionValue#(bit) vga_blank(); (* always_ready, always_enabled *) method ActionValue#(bit) vga_sync(); endinterface: DVI_Colour_Bars_Interface

37 (* synthesize *) module mkDVI_Colour_bars (DVI_Colour_Bars_Interface) ; Reg#(bit) vga_hsx <- mkReg(0) ; Reg#(bit) vga_vsx <- mkReg(0) ; Reg#(int) col <- mkReg (0) ; Reg#(int) row <- mkReg (0) ; Reg#(Bit#(10)) vga_rx <- mkReg (0) ; Reg#(Bit#(10)) vga_gx <- mkReg (0) ; Reg#(Bit#(10)) vga_bx <- mkReg (0) ; Reg#(Bool) resetDone <- mkReg (False) ; Reg#(Bool) valid_h <- mkReg (False) ; Reg#(Bool) valid_v <- mkReg (False) ; int h_pixels_width = 640 ; int h_pixels_front_porch = 16 ; int h_pixels_sync = 96 ; int h_pixels_back_porch = 48 ; int h_pixels_total = h_pixels_width + h_pixels_front_porch + h_pixels_sync + h_pixels_back_porch ; int v_pixels_height = 480 ; int v_pixels_front_porch = 10 ; int v_pixels_sync = 2 ; int v_pixels_back_porch = 33 ; int v_pixels_total = v_pixels_height + v_pixels_front_porch + v_pixels_sync + v_pixels_back_porch ;

38 // Perform a reset by setting row and col to zero rule performReset (!resetDone) ; col <= 0 ; row <= 0 ; resetDone <= True ; endrule // Compute valid_h and valid_v rule compute_valid ; valid_h <= col < h_pixels_width ; valid_v <= row < v_pixels_height ; endrule // Advance row and col rule advance_row_and_col ; if (col == h_pixels_total - 1) begin if (row == v_pixels_total - 1) row <= 0 ; else row <= row + 1 ; col <= 0 ; end else col <= col + 1 ; endrule

39 // Generate HSYNC rule generate_hsync ; if (col < h_pixels_width + h_pixels_front_porch || col > h_pixels_width + h_pixels_front_porch + h_pixels_sync) vga_hsx <= 1 ; else vga_hsx <= 0 ; endrule // Generate VSYNC rule generate_vsync ; if (row < v_pixels_height + v_pixels_front_porch || row > v_pixels_height + v_pixels_front_porch + v_pixels_sync) vga_vsx <= 1 ; else vga_vsx <= 0 ; endrule

40 // Red bar rule red_bar (valid_v && valid_h && col < 100) ; vga_rx <= 'h3FF ; vga_gx <= 0 ; vga_bx <= 0 ; endrule // Green bar rule green_bar (valid_v && valid_h && col >= 100 && col < 200) ; vga_rx <= 0 ; vga_gx <= 'h3FF ; vga_bx <= 0 ; endrule // Blue bar rule blue_bar (valid_v && valid_h && col >= 200 && col < 300) ; vga_rx <= 0 ; vga_gx <= 0 ; vga_bx <= 'h3FF ; endrule // Yellow bar rule x1_bar (valid_v && valid_h && col >= 300 && col < 400) ; vga_rx <= 'h3FF ; vga_gx <= 'h3FF ; vga_bx <= 0 ; endrule

41

42

43

44 Host PC RAMP BEE3 System images GB Ethernet images commands FPGA XCVLX110T FPGA XCVLX110T 8 GB DDR2 FPGA XCVLX110T FPGA XCVLX110T 8 GB DDR2 images JTAG & RS232

45

46 Ethernet LocalLink Protocol

47

48 interface SyncFIFOIfc #(type a_type) ; method Action enq (a_type sendData ) ; method Action deq () ; method a_type first () ; method Bool notFull () ; method Bool notEmpty () ; endinterface Class of synchronous FIFOs module mkSyncFIFOFromCC #(Integer depth, Clock dClkIn) (SyncFIFOIfc #(a_type)) SyncFIFOIfc#(Bit#(8)) fifo_in <- mkSyncFIFOFromCC (2000, clientClock) ;

49 SyncFIFOCountIfc interface SyncFIFOCountIfc#(type element_type, numeric type fifoDepth) ; method Action enq ( element_type sendData ) ; method Action deq () ; method element_type first () ; method Bool sNotFull ; method Bool sNotEmpty ; method Bool dNotFull ; method Bool dNotEmpty ; method UInt#(TLog#(TAdd#(fifoDepth,1))) sCount; method UInt#(TLog#(TAdd#(fifoDepth,1))) dCount; method Action sClear; method Action dClear; endinterface

50 mkSyncFIFOCount SyncFIFOCountIfc#(Bit#(8), 2048) fifo_out <- mkSyncFIFOCount (clientClock, clientReset, currentClock) ;

51 Signalling Across Clock Domains interface SyncPulseIfc ; method Action send () ; method Bool pulse () ; endinterface module mkSyncPulseToCC #(Clock sClkIn, Reset sRstIn) (SyncPulseIfc) ; SyncPulseIfc flusher <- mkSyncPulseToCC (clientClock, clientReset) ; SyncPulseIfc nextPacket <- mkSyncPulseToCC (clientClock, clientReset) ;

52 LocalLink Interface interface LocalLink_Interface ; interface SyncFIFOIfc#(Bit#(8)) rx_fifo ; interface SyncFIFOCountIfc#(Bit#(8), 2048) tx_fifo ; interface LocalLink_Ports localLink_ports ; interface SyncPulseIfc flush ; interface SyncPulseIfc readyForNextPacket ; endinterface: LocalLink_Interface

53 LocalLink Ports interface LocalLink_Ports ; // RX Interface (* always_enabled *) method Action rx_data (Bit#(8) in) ; (* always_enabled *) method Action rx_sof_n (bit in) ; (* always_enabled *) method Action rx_eof_n (bit in) ; (* always_enabled *) method Action rx_src_rdy_n (bit in) ; (* always_ready *) method bit rx_dst_rdy_n ; // TX Interface (* always_ready *) method Bit#(8) tx_data ; (* always_ready *) method bit tx_sof_n ; (* always_ready *) method bit tx_eof_n ; (* always_ready *) method bit tx_src_rdy_n ; (* always_enabled *) method Action tx_dst_rdy_n (bit in) ; endinterface: LocalLink_Ports

54 Counter Rule Reg#(int) cycle <- mkReg (0) ;... rule cycleCounter ; cycle <= cycle + 1 ; endrule

55 States typedef enum {Ready_for_frame, Reading_frame, Frame_read, Serving_frame} LL_state deriving (Bounded, Bits, Eq) ; Reg#(LL_state) recv_state <- mkReg (Ready_for_frame) ;

56 Start of Frame Rule rule enqueueSOFData (rx_src_rdy_n_input == 0 && rx_sof_n_input == 0 && recv_state == Ready_for_frame) ; fifo_in.enq (rx_data_input) ; recv_state <= Reading_frame ; endrule

57 DDR2 Memory Controller interface DDR2_Controller_Interface ; method Action write (Bit#(28) addr, Bit#(288) data) ; method Action issue_read (Bit#(28) addr) ; method ActionValue#(Bit#(288)) read_value ; interface DDR2_Interface ddr2_intf ; endinterface: DDR2_Controller_Interface

58 DDR Interface interface DDR2_Interface ; (* always_enabled *) method Action readStop (Bool in) ; (* always_enabled *) method Action writeStop (Bool in) ; (* always_ready *) method Bit#(31) af ; (* always_ready *) method Bool writeAF ; (* always_enabled *) method Bit#(144) wb ; (* always_enabled *) method Bool writeWB ; (* always_enabled *) method Action rbNonEmpty (Bool in) ; (* always_enabled *) method Action rb (Bit#(144) in) ; (* always_ready *) method Bool readRB ; endinterface: DDR2_Interface

59 Stmt write_statements = seq action wb_out <= data_value[143:0] ; writeWB_out <= True ; endaction writeWB_out <= False ; action wb_out <= data_value[287:144] ; writeWB_out <= True ; endaction action writeWB_out <= False ; af_out <= {3'b100, rw_addr} ; writeAF_out <= True ; endaction writeAF_out <= False ; endseq ; FSM write_fsm <- mkFSM (write_statements) ;

60 function Bit#(24) grayPixel (Bit#(24) rgb_bits) ; Vector#(3, UInt#(8)) rgb = unpack (rgb_bits) ; UInt#(17) grayValue = (extend(rgb[2]) * 77 + extend(rgb[1]) * 151 + extend(rgb[0]) * 28) / 256 ; Vector#(3, UInt#(8)) grayVec ; grayVec[0] = truncate (grayValue) ; // gray blue channel grayVec[1] = truncate (grayValue) ; // gray green channel grayVec[2] = truncate (grayValue) ; // gray red channel return pack (grayVec) ; endfunction for (Integer i = 0; i < 12; i = i + 1) resultPix[i] = grayPixel (pix[i]) ;

61 Stmt process_image_statements = seq for (addr <= 0; addr <= top; addr <= addr +1) seq dram.issue_read (addr) ; action let read_value <- dram.read_value ; dataIn <= read_value ; endaction gray12circuit.gray12 (dataIn) ; dataOut <= unpack (gray12circuit.gray_result) ; dram.write (addr, pack (dataOut)) ; endseq endseq ; FSM process_image_fsm <- mkFSM (process_image_statements) ;

62 method ActionValue#(Bit#(288)) read_value if (state == DataAvailable) ; state <= Idle ; return data_value ; endmethod

63 Stmt read_statements = seq action af_out <= {3'b101, rw_addr} ; writeAF_out <= True ; endaction writeAF_out <= False ; await (rbNonEmpty_input) ; readRB_out <= True ; action readRB_out <= False ; data_value[143:0] <= rb_input ; endaction delay (4) ; readRB_out <= True ; action readRB_out <= False ; data_value[287:144] <= rb_input ; endaction endseq ;

64 addrVec <= pack(addr)[27:0] ; while (numWrites > 0) seq for (i <= 0; i < 36 ; i <= i + 1) action local_link.rx_fifo.deq ; dataOut[i] <= local_link.rx_fifo.first ; endaction dram.write (addrVec, pack(dataOut)) ; addrVec <= addrVec + 1 ; numWrites <= numWrites -1 ; endseq

65 Other Practical Matters C++ implementation of Adobe Photoshop filters that communicate with BEE3 board over Ethernet (Adobe SDK). NDISPROT driver for sending raw Ethernet packets on Windows.

66 Implementation XCVLX110T Xilinx FPGA GMII/Ethernet interface at 125MHz Memory access operations at 100MHz 14,161 LUTs (20%) 5,075 registers (7%)


Download ppt "Bluespec Lectures 1 & 2. Contact Information Satnam Singh Web:"

Similar presentations


Ads by Google