#NEWLINE# def mkMatmulBram( n = 16 , datawidth = 32 ) : #NEWLINE# #INDENT# m = Module ( 'Matmul' ) #NEWLINE# clk = m . Input ( 'CLK' ) #NEWLINE# rst = m . Input ( 'RST' ) #NEWLINE# addrwidth = ( int ( math . log ( n , 2 ) ) * 2 ) #NEWLINE# bram = mkBram ( datawidth , addrwidth ) #NEWLINE# ext_ports = [ ] #NEWLINE# for i in range ( 3 ) : #NEWLINE# #INDENT# addr = m . Input ( ( 'bram_addr%d' % i ) , addrwidth ) #NEWLINE# din = m . Input ( ( 'bram_din%d' % i ) , datawidth ) #NEWLINE# we = m . Input ( ( 'bram_we%d' % i ) ) #NEWLINE# dout = m . Output ( ( 'bram_dout%d' % i ) , datawidth ) #NEWLINE# ext_ports . append ( [ addr , din , we , dout ] ) #NEWLINE# #UNINDENT# int_ports = [ ] #NEWLINE# for i in range ( 3 ) : #NEWLINE# #INDENT# addr = m . Wire ( ( '_addr%d' % i ) , addrwidth ) #NEWLINE# din = m . Wire ( ( '_din%d' % i ) , datawidth ) #NEWLINE# we = m . Wire ( ( '_we%d' % i ) ) #NEWLINE# dout = m . Wire ( ( '_dout%d' % i ) , datawidth ) #NEWLINE# int_ports . append ( [ addr , din , we , dout ] ) #NEWLINE# #UNINDENT# for i in range ( 3 ) : #NEWLINE# #INDENT# ports = ( ( [ clk ] + bram [ i ] ) + int_ports [ i ] ) #NEWLINE# m . Instance ( bram , ( 'inst_bram%d' % i ) , ports = ports ) #NEWLINE# #UNINDENT# xaddr = m . Reg ( 'xaddr' , addrwidth , initval = 0 ) #NEWLINE# xdin = m . Wire ( 'xdin' , datawidth ) #NEWLINE# yaddr = m . Reg ( 'yaddr' , addrwidth , initval = 0 ) #NEWLINE# ydin = m . Wire ( 'ydin' , datawidth ) #NEWLINE# zaddr = m . Reg ( 'zaddr' , addrwidth , initval = 0 ) #NEWLINE# zdout = m . Reg ( 'zdout' , datawidth , initval = 0 ) #NEWLINE# zwe = m . Reg ( 'zwe' ) #NEWLINE# ( addr , din , we , dout ) = int_ports [ 0 ] #NEWLINE# m . Assign ( addr ( xaddr ) ) #NEWLINE# m . Assign ( we ( 0 ) ) #NEWLINE# m . Assign ( xdin ( dout ) ) #NEWLINE# ( addr , din , we , dout ) = int_ports [ 1 ] #NEWLINE# m . Assign ( addr ( yaddr ) ) #NEWLINE# m . Assign ( we ( 0 ) ) #NEWLINE# m . Assign ( ydin ( dout ) ) #NEWLINE# ( addr , din , we , dout ) = int_ports [ 2 ] #NEWLINE# m . Assign ( addr ( zaddr ) ) #NEWLINE# m . Assign ( din ( zdout ) ) #NEWLINE# m . Assign ( we ( zwe ) ) #NEWLINE# start = m . Input ( 'start' ) #NEWLINE# busy = m . OutputReg ( 'busy' , initval = 0 ) #NEWLINE# madd = mkMadd ( ) #NEWLINE# ivalid = m . Reg ( 'ivalid' , initval = 0 ) #NEWLINE# odata = m . Wire ( 'odata' , datawidth ) #NEWLINE# ovalid = m . Wire ( 'ovalid' ) #NEWLINE# vreset = m . Reg ( 'vreset' , initval = 0 ) #NEWLINE# m . Instance ( madd , 'madd' , ports = [ ( 'CLK' , clk ) , ( 'RST' , rst ) , ( 'xd' , xdin ) , ( 'xv' , ivalid ) , ( 'yd' , ydin ) , ( 'yv' , ivalid ) , ( 'zd' , odata ) , ( 'zv' , ovalid ) , ( 'vreset_data' , 0 ) , ( 'vreset' , vreset ) ] ) #NEWLINE# read_count = m . TmpReg ( ( int ( ( addrwidth / 2 ) ) + 1 ) , initval = 0 ) #NEWLINE# sum_value = m . TmpReg ( datawidth , initval = 0 ) #NEWLINE# sum_count = m . TmpReg ( ( int ( ( addrwidth / 2 ) ) + 1 ) , initval = 0 ) #NEWLINE# fsm = FSM ( m , 'fsm' , clk , rst ) #NEWLINE# init = fsm . current ( ) #NEWLINE# fsm . add ( xaddr ( ( 0 - 1 ) ) , yaddr ( ( 0 - 1 ) ) , zaddr ( ( 0 - 1 ) ) , zwe ( 0 ) , busy ( 0 ) , vreset ( 1 ) , ivalid ( 0 ) , read_count ( 0 ) , sum_value ( 0 ) , sum_count ( 0 ) ) #NEWLINE# fsm . add ( busy ( 1 ) , vreset ( 0 ) , cond = start ) #NEWLINE# fsm . goto_next ( cond = start ) #NEWLINE# comp = fsm . current ( ) #NEWLINE# fsm . add ( xaddr . inc ( ) , yaddr . inc ( ) , cond = ( read_count < n ) ) #NEWLINE# fsm . add ( ivalid ( 0 ) , delay = 1 ) #NEWLINE# fsm . add ( ivalid ( 1 ) , delay = 1 , cond = ( read_count < n ) ) #NEWLINE# fsm . add ( read_count . inc ( ) , cond = ( read_count < n ) ) #NEWLINE# fsm . add ( sum_count . inc ( ) , cond = ovalid ) #NEWLINE# fsm . add ( sum_value ( odata ) , cond = ovalid ) #NEWLINE# fsm . goto_next ( cond = ( sum_count == n ) ) #NEWLINE# fsm . add ( zaddr . inc ( ) ) #NEWLINE# fsm . add ( zdout ( sum_value ) , zwe ( 1 ) ) #NEWLINE# fsm . add ( zwe ( 0 ) , delay = 1 ) #NEWLINE# fsm . add ( yaddr ( ( 0 - 1 ) ) , cond = ( yaddr == ( ( n * n ) - 1 ) ) ) #NEWLINE# fsm . add ( xaddr ( ( xaddr - n ) ) , cond = ( yaddr < ( ( n * n ) - 1 ) ) ) #NEWLINE# fsm . add ( read_count ( 0 ) , sum_count ( 0 ) ) #NEWLINE# fsm . add ( vreset ( 1 ) ) #NEWLINE# fsm . add ( vreset ( 0 ) , delay = 1 ) #NEWLINE# done = ( zaddr == ( ( n * n ) - 2 ) ) #NEWLINE# fsm . goto ( comp , cond = Not ( done ) ) #NEWLINE# fsm . goto ( init , cond = done ) #NEWLINE# fsm . make_always ( ) #NEWLINE# return m