def test(): params = vast.Paramlist([]) clk = vast.Ioport(vast.Input('CLK')) rst = vast.Ioport(vast.Input('RST')) width = vast.Width(vast.IntConst('7'), vast.IntConst('0')) led = vast.Ioport(vast.Output('led', width=width), vast.Reg('led', width=width)) ports = vast.Portlist((clk, rst, led)) items = [ vast.EmbeddedCode(""" // Embedded code reg [31:0] count; always @(posedge CLK) begin if(RST) begin count <= 0; led <= 0; end else begin if(count == 1024 - 1) begin count <= 0; led <= led + 1; end else begin count <= count + 1; end end end """) ] ast = vast.ModuleDef("top", params, ports, items) codegen = ASTCodeGenerator() rslt = codegen.visit(ast) print(rslt) assert (expected == rslt)
def visit_Reg(self, node): name = node.name if self.module.is_output(name): return None width = self.make_width(node) dims = self.make_dims(node) signed = node.signed return vast.Reg(name, width, signed, dims)
def visit_Output(self, node): name = node.name width = self.make_width(node) dims = self.make_dims(node) signed = node.signed first = vast.Output(name, width, signed, dims) second = vast.Reg(name, width, signed, dims) if self.module.is_reg(name) else None return vast.Ioport(first, second)
def test(): datawid = vast.Parameter( 'DATAWID', vast.Rvalue(vast.IntConst('32')) ) params = vast.Paramlist( [datawid] ) clk = vast.Ioport( vast.Input('CLK') ) rst = vast.Ioport( vast.Input('RST') ) width = vast.Width( vast.IntConst('7'), vast.IntConst('0') ) led = vast.Ioport( vast.Output('led', width=width) ) ports = vast.Portlist( [clk, rst, led] ) width = vast.Width( vast.Minus(vast.Identifier('DATAWID'), vast.IntConst('1')), vast.IntConst('0') ) count = vast.Reg('count', width=width) assign = vast.Assign( vast.Lvalue(vast.Identifier('led')), vast.Rvalue( vast.Partselect( vast.Identifier('count'), # count vast.Minus(vast.Identifier('DATAWID'), vast.IntConst('1')), # [DATAWID-1: vast.Minus(vast.Identifier('DATAWID'), vast.IntConst('8'))))) # :DATAWID-8] sens = vast.Sens(vast.Identifier('CLK'), type='posedge') senslist = vast.SensList([ sens ]) assign_count_true = vast.NonblockingSubstitution( vast.Lvalue(vast.Identifier('count')), vast.Rvalue(vast.IntConst('0'))) if0_true = vast.Block([ assign_count_true ]) # (count + 1) * 2 count_plus_1 = vast.Plus(vast.Identifier('count'), vast.IntConst('1')) cp1_times_2 = vast.Times(count_plus_1, vast.IntConst('2')) cp1t2_plus_1 = vast.Plus(cp1_times_2, vast.IntConst('1')) assign_count_false = vast.NonblockingSubstitution( vast.Lvalue(vast.Identifier('count')), vast.Rvalue(cp1t2_plus_1)) if0_false = vast.Block([ assign_count_false ]) if0 = vast.IfStatement(vast.Identifier('RST'), if0_true, if0_false) statement = vast.Block([ if0 ]) always = vast.Always(senslist, statement) items = [] items.append(count) items.append(assign) items.append(always) ast = vast.ModuleDef("top", params, ports, items) codegen = ASTCodeGenerator() rslt = codegen.visit(ast) print(rslt) assert(expected == rslt)
def visit_Output(self, node): name = node.name width = (None if node.width is None else self.make_width_msb_lsb(node.width_msb, node.width_lsb) if node.width_msb is not None and node.width_lsb is not None else self.make_width(node.width)) signed = node.signed first = vast.Output(name, width, signed) second = vast.Reg(name, width, signed) if self.module.is_reg(name) else None return vast.Ioport(first, second)
def visit_Reg(self, node): name = node.name if self.module.is_output(name): return None width = (None if node.width is None else self.make_width_msb_lsb(node.width_msb, node.width_lsb) if node.width_msb is not None and node.width_lsb is not None else self.make_width(node.width)) length = (None if node.length is None else self.make_length_msb_lsb(node.length_msb, node.length_lsb) if node.length_msb is not None and node.length_lsb is not None else self.make_length(node.length)) signed = node.signed if length is not None: return vast.RegArray(name, width, length, signed) return vast.Reg(name, width, signed)
def lower_fsm(fsm: FSM): assert fsm.start_state == 0, "Starting state is not 0" zero = vast.IntConst(0) all_registers = [ Register("a", 8), Register("b", 8), Register("tmp", 8), Register("_cond", 1), ] register_defs = [ vast.Reg( reg.name, vast.Width(vast.IntConst(reg.width - 1), zero) if reg.width - 1 != 0 else None) for reg in all_registers ] ports = vast.Portlist([ vast.Ioport(vast.Input('clk')), # XXX(rachit): AST can't represent `output reg done` # so assign to a local register and use a wire. vast.Ioport(vast.Output('done')), ]) done_state = max(fsm.actions.keys()) + 1 done_reg = vast.Reg('done_out') hook_up_done = vast.Assign( vast.Lvalue(vast.Identifier('done')), vast.Rvalue(vast.Identifier('done_out')), ) # Register to store the FSM state. fsm_reg_size = int(math.ceil(math.log2(done_state))) + 1 fsm_reg = vast.Reg(name="fsm_reg", width=vast.Width(vast.IntConst(fsm_reg_size - 1), zero)) # Define all the registers. reg_decl = register_defs + [fsm_reg] # Define the initial process inits = vast.Initial( vast.Block([ vast.BlockingSubstitution( vast.Lvalue(vast.Identifier(reg.name)), vast.Rvalue(vast.IntConst(0)), ) for reg in reg_decl ])) # Default case, assigns to the done register. done = vast.IntConst(done_state) default_case = vast.Case(cond=None, statement=vast.Block([ vast.NonblockingSubstitution( vast.Lvalue(vast.Identifier(reg.name)), vast.Rvalue(vast.Identifier(reg.name)), ) for reg in reg_decl ] + [ vast.NonblockingSubstitution( vast.Lvalue(vast.Identifier('done_out')), vast.Rvalue(vast.IntConst(1))) ])) # Generate Case conditions for each transition. cases = [ vast.Case([vast.IntConst(cond_val)], lower_action(fsm_reg, done, action)) for (cond_val, action) in fsm.actions.items() ] case_statement = vast.CaseStatement(comp=vast.Identifier(fsm_reg.name), caselist=cases + [default_case]) always_ff = vast.Always( vast.SensList([vast.Sens(vast.Identifier('clk'), 'posedge')]), vast.Block([case_statement])) return vast.ModuleDef(name="main", paramlist=vast.Paramlist([]), portlist=ports, items=reg_decl + [done_reg, hook_up_done, inits, always_ff])