def test(): PC_src_sel.next = PC_JAL_TARGET yield delay(10) assert PC_PIF == modbv(PC_DX + jal_offset)[XPR_LEN:] PC_src_sel.next = PC_JALR_TARGET yield delay(10) assert PC_PIF == modbv(rs1_data + jalr_offset)[XPR_LEN:] PC_src_sel.next = PC_BRANCH_TARGET yield delay(10) assert PC_PIF == modbv(PC_DX + imm_b)[XPR_LEN:] PC_src_sel.next = PC_REPLAY yield delay(10) assert PC_PIF == PC_IF PC_src_sel.next = PC_HANDLER yield delay(10) assert PC_PIF == handler_PC PC_src_sel.next = PC_EPC yield delay(10) assert PC_PIF == epc PC_src_sel.next = PC_PLUS_FOUR yield delay(10) assert PC_PIF == modbv(PC_IF + 4)[XPR_LEN:]
def write_process1(): if state_m == bp_states_m.WRITE1: index_r = random[26:20] #btb_line[index_r][64:63].next = Signal(True) #Set Valid Bit #btb_line[index_r][61:32].next = tag_pc[32:2] #Store tag if BPio.valid_jump: btb_line[index_r].next = concat(True,True,modbv(tag_pc[32:2])[30:],modbv(BPio.pc_id_brjmp[32:2])[30:],modbv(Consts.ST)[2:]) # btb_line[index_r][63:62].next = Signal(True) #Set Unconditional Bit # btb_line[index_r][2:0].next = Consts.ST #As a jump it'll always be ST # BPio.current_state.next = Consts.ST #Send our current state to Cpath # btb_line[index_r][32:2].next = BPio.pc_id_brjmp[32:2] #Store jump address in BTB elif BPio.valid_branch: btb_line[index_r].next = concat(True,False,modbv(tag_pc[32:2])[30:],modbv(BPio.pc_id_brjmp[32:2])[30:],modbv(Consts.WN)[2:]) #btb_line[index_r][63:62].next = Signal(False) #Clear unconditional bit #btb_line[index_r][2:0].next = Consts.WN #It will be initialized in WN #BPio.current_state.next = Consts.WN #Send our current state to Cpath #btb_line[index_r][32:2].next = BPio.pc_id_brjmp[32:2] #Store Branch address in BTB else: #Corresponding to JALR #btb_line[index_r][63:62] = Signal(True) #Set Unconditional bit #btb_line[index_r][2:0] = Consts.ST #As an indirect jump it'll always be taken #BPio.current_state.next = Consts.ST #Send our current state to Cpath #btb_line[index_r][32:2] = BPio.pc_id_jalr[32:2] #Store jump address in BTB btb_line[index_r].next = concat(True,True,modbv(tag_pc[32:2])[30:],modbv(BPio.pc_id_jalr[32:2])[30:],modbv(Consts.ST)[2:]) final_write1.next = True
def Test(): depth = 4 width = 4 dout = Signal(modbv(0)[width:]) din = Signal(modbv(0)[width:]) full = Signal(bool(0)) empty = Signal(bool(0)) push = Signal(bool(0)) clk = Signal(bool(0)) stack = Stack(dout, din, full, empty, push, clk, width=width, depth=depth) @instance def stimulus(): print('dout\tdin\tfull\tempty\tpush') push.next = 1 for k in range(16): din.next = k + 1 push.next = k < 8 yield delay(10) clk.next = 1 yield delay(10) clk.next = 0 print(dout, din, full, empty, push, sep='\t') return instances()
def test_register_file(): clock, write_enable = [Signal(False) for _ in range(2)] read_addr1, read_addr2, write_addr = [Signal(modbv(0)[REG_ADDR_WIDTH:]) for _ in range(3)] read_data1, read_data2, write_data = [Signal(modbv(0)[XPR_LEN:]) for _ in range(3)] reg_file_inst = register_file(clock, read_addr1, read_data1, read_addr2, read_data2, write_enable, write_addr, write_data) reg_file_inst.convert(hdl='Verilog') rand_value = randint(1, (1 << XPR_LEN) - 1) rand_addr = randint(1, (1 << REG_ADDR_WIDTH) - 1) @always(delay(1)) def drive_clock(): clock.next = not clock @instance def test(): write_enable.next = True yield clock.posedge write_data.next = rand_value write_addr.next = rand_addr yield clock.posedge read_addr1.next = rand_addr read_addr2.next = rand_addr yield clock.posedge assert rand_value == read_data1 == read_data2 return test, reg_file_inst, drive_clock
def led_dance( # ~~~[Ports]~~~ clock, # input : system sync clock reset, # input : reset (level determined by RST_LEVEL) leds, # output : to IO ports drive LEDs # ~~~[Parameters]~~~ led_rate=33e-3, # strobe change rate of 333ms ): """ """ gens = [] cnt_max = int(clock.frequency * led_rate) clk_cnt = Signal(intbv(1, min=0, max=cnt_max)) rled = Signal(modbv(0)[len(leds):]) # assign the port LED to the internal register led gas = assign(leds, rled) # @todo: create a module to select a rate strobe, # the module will return a signal that is from # an existing rate or a generator and signal mb = len(leds)-1 d = modbv(0)[len(leds):] @always_seq(clock.posedge, reset=reset) def rtl(): if clk_cnt == 0: d[:] = (rled ^ 0x81) << 1 rled.next = concat(d, rled[mb]) clk_cnt.next = clk_cnt + 1 gens += (gas, rtl,) return gas, rtl
def fifo_async(clock_write, clock_read, fifobus, reset, size=128): """ The following is a general purpose, platform independent asynchronous FIFO (dual clock domains). Cross-clock boundary FIFO, based on: "Simulation and Synthesis Techniques for Asynchronous FIFO Design" Typically in the "rhea" package the FIFOBus interface is used to interface with the FIFOs """ # @todo: use the clock_write and clock_read from the FIFOBus # @todo: interface, make this interface compliant with the # @todo: fifos: fifo_async(reset, clock, fifobus) # for simplification the memory size is forced to a power of # two - full address range, ptr (mem indexes) will wrap asz = int(ceil(log(size, 2))) fbus = fifobus # alias # an extra bit is used to determine full vs. empty (see paper) waddr = Signal(modbv(0)[asz:]) raddr = Signal(modbv(0)[asz:]) wptr = Signal(modbv(0)[asz+1:]) rptr = Signal(modbv(0)[asz+1:]) wq2_rptr = Signal(intbv(0)[asz+1:]) rq2_wptr = Signal(intbv(0)[asz+1:]) wfull = Signal(bool(0)) rempty = Signal(bool(1)) # sync'd resets, the input reset is more than likely sync'd to one # of the clock domains, sync both regardless ... wrst = ResetSignal(reset.active, active=reset.active, async=reset.async)
def UIntToFloat( float_output, uint_input, exponent_width, fraction_width, exponent_bias ): # Calculating unbiased and biased exponent. unbiased_exponent = Signal(modbv(0)[exponent_width:]) biased_exponent = Signal(modbv(0)[exponent_width:]) nz_flag = Signal(bool(0)) unbiased_exponent_calculator = PriorityEncoder( unbiased_exponent, nz_flag, uint_input) @always_comb def biased_exponent_calculator(): biased_exponent.next = unbiased_exponent + exponent_bias # Calculating fraction part. fraction = Signal(modbv(0)[fraction_width:]) fraction_calculator = UIntToFraction( fraction, uint_input, unbiased_exponent) float_sig = ConcatSignal(bool(0), biased_exponent, fraction) @always_comb def make_output(): if uint_input == 0: float_output.next = 0 else: float_output.next = float_sig return instances()
def Test(): # IEEE754 Single EXPONENT_WIDTH = 8 FRACTION_WIDTH = 23 EXPONENT_BIAS = 127 INT_WIDTH = 6 float_sig = Signal(modbv(0)[(1+EXPONENT_WIDTH+FRACTION_WIDTH):]) int_sig = Signal(modbv(0)[INT_WIDTH:]) convertor = IntToFloat( float_sig, int_sig, exponent_width=EXPONENT_WIDTH, fraction_width=FRACTION_WIDTH, exponent_bias=EXPONENT_BIAS) @instance def stimulus(): print('input', 'output', sep='\t') for k in range(-2**(INT_WIDTH-1), 2**(INT_WIDTH-1)): int_sig.next = k yield delay(10) int_val = int(int_sig) if k < 0: int_val = ~int_val + 1 int_val &= 2**INT_WIDTH - 1 int_val = -int_val print(int_val, uint_to_float(int(float_sig))[0], sep='\t') return instances()
def __init__(self): """ Initializes the IO ports. """ self.wa = Signal(modbv(0)[5:]) self.we = Signal(False) self.wd = Signal(modbv(0)[32:])
def IntToFloat( float_output, int_input, exponent_width, fraction_width, exponent_bias): INT_WIDTH = len(int_input) FLOAT_WIDTH = len(float_output) sign = Signal(bool(0)) sign_getter = SignGetter(sign, int_input) abs_int = Signal(modbv(0)[INT_WIDTH:]) abs_calculator = Abs(abs_int, int_input) abs_float = Signal(modbv(0)[(1+exponent_width+fraction_width):]) float_calculator = UIntToFloat( abs_float, abs_int, exponent_width, fraction_width, exponent_bias) signed_float = ConcatSignal(sign, abs_float(FLOAT_WIDTH-1, 0)) @always_comb def make_output(): float_output.next = signed_float return instances()
def assignments_0(): sign_a.next = io.input1[31] if (io.cmd[0] or io.cmd[2]) else modbv(0)[1:] sign_b.next = io.input2[31] if io.cmd[0] else modbv(0)[1:] partial_sum.next = concat(modbv(0)[15:], result_mid_1) + concat(result_hh_1[32:], result_ll_1[32:16]) io.output.next = -result_mult if sign_result3 else result_mult io.ready.next = active3 io.active.next = active0 | active1 | active2 | active3
def rtl(): b30_20.next = ( instruction[31:20] if sel == Consts.IMM_U else concat(sign, sign, sign, sign, sign, sign, sign, sign, sign, sign, sign) ) b19_12.next = ( instruction[20:12] if (sel == Consts.IMM_U or sel == Consts.IMM_UJ) else concat(sign, sign, sign, sign, sign, sign, sign, sign) ) b11.next = ( False if (sel == Consts.IMM_U or sel == Consts.IMM_Z) else (instruction[20] if sel == Consts.IMM_UJ else (instruction[7] if sel == Consts.IMM_SB else sign)) ) b10_5.next = modbv(0)[6:] if (sel == Consts.IMM_U or sel == Consts.IMM_Z) else instruction[31:25] b4_1.next = ( modbv(0)[4:] if sel == Consts.IMM_U else ( instruction[12:8] if (sel == Consts.IMM_S or sel == Consts.IMM_SB) else (instruction[20:16] if sel == Consts.IMM_Z else instruction[25:21]) ) ) b0.next = ( instruction[7] if sel == Consts.IMM_S else (instruction[20] if sel == Consts.IMM_I else (instruction[15] if sel == Consts.IMM_Z else False)) )
def state_machine(): if state == s_idle: if req_valid: result.next = 0 a.next = abs_in_1 b.next = concat(abs_in_2, modbv(0)[XPR_LEN:]) >> 1 if op == MD_OP_REM: negate_output.next = sign_in_1 else: negate_output.next = sign_in_1 ^ sign_in_2 out_sel.next = req_out_sel op.next = req_op counter.next = XPR_LEN - 1 elif state == s_compute: counter.next = counter + 1 b.next = b >> 1 if op == MD_OP_MUL: if a[counter]: result.next = result + b else: b.next = b + 1 if a_geq: a.next = a - b result.next = modbv(1 << counter)[DOUBLE_XPR_LEN:] | result elif state == s_setup_output: result.next = concat(modbv(0)[XPR_LEN:], final_result)
def accessor(): if state == state_t.READY: coeff_ram_blk.next = True if enable and in_valid: delay_line_i_ram_addr.next = concat(bank1, bank0, n) delay_line_i_ram_din.next = in_i delay_line_i_ram_blk.next = False delay_line_i_ram_wen.next = False delay_line_q_ram_addr.next = concat(bank1, bank0, n) delay_line_q_ram_din.next = in_q delay_line_q_ram_blk.next = False delay_line_q_ram_wen.next = False else: delay_line_i_ram_blk.next = True delay_line_q_ram_blk.next = True elif state == state_t.WAIT1 or state == state_t.WAIT2 or state == state_t.RUN: delay_line_i_ram_addr.next = concat(bank1, bank0, modbv(n - k, min=0, max=2**7-1)) delay_line_i_ram_blk.next = False delay_line_i_ram_wen.next = True delay_line_q_ram_addr.next = concat(bank1, bank0, modbv(n - k, min=0, max=2**7-1)) delay_line_q_ram_blk.next = False delay_line_q_ram_wen.next = True coeff_ram_addr.next = concat(bank1, bank0, k) coeff_ram_blk.next = False coeff_ram_wen.next = True else: delay_line_i_ram_blk.next = True delay_line_q_ram_blk.next = True coeff_ram_blk.next = True
def led_dance(clock, reset, leds, led_rate=33e-3): """An interesting LED pattern Arguments: clock: system clock reset: system reset leds: LED bits Parameters: led_rate: the rate to blink, in seconds """ cnt_max = int(clock.frequency * led_rate) clk_cnt = Signal(intbv(1, min=0, max=cnt_max)) rled = Signal(modbv(0)[len(leds):]) # assign the port LED to the internal register led assign(leds, rled) # @todo: create a module to select a rate strobe, # the module will return a signal that is from # an existing rate or a generator and signal mb = len(leds)-1 d = modbv(0)[len(leds):] @always_seq(clock.posedge, reset=reset) def beh(): if clk_cnt == 0: d[:] = (rled ^ 0x81) << 1 rled.next = concat(d, rled[mb]) clk_cnt.next = clk_cnt + 1 return myhdl.instances()
def __init__(self): self.input1 = Signal(modbv(0)[32:]) self.input2 = Signal(modbv(0)[32:]) self.function = Signal(modbv(0)[ALUOp.SZ_OP:]) self.stall = Signal(False) self.kill = Signal(False) self.output = Signal(modbv(0)[32:]) self.req_stall = Signal(False)
def convert(): shifted = Signal(modbv(0)[32:]) data = Signal(modbv(0)[32:]) num = Signal(modbv(0)[5:]) direction = Signal(bool(0)) inst = MultShifter(shifted=shifted, data=data, direction=direction, num=num) inst.convert(hdl='verilog')
def IMMGen(sel, instruction, imm): """ Generate the immediate values. :param sel: Select the type of instruction/immediate :param instruction: Current instruction :param imm: A 32-bit immediate value """ sign = Signal(False) b30_20 = Signal(modbv(0)[11:]) b19_12 = Signal(modbv(0)[8:]) b11 = Signal(False) b10_5 = Signal(modbv(0)[6:]) b4_1 = Signal(modbv(0)[4:]) b0 = Signal(False) @always_comb def _sign(): sign.next = False if sel == Consts.IMM_Z else instruction[31] @always_comb def rtl(): b30_20.next = ( instruction[31:20] if sel == Consts.IMM_U else concat(sign, sign, sign, sign, sign, sign, sign, sign, sign, sign, sign) ) b19_12.next = ( instruction[20:12] if (sel == Consts.IMM_U or sel == Consts.IMM_UJ) else concat(sign, sign, sign, sign, sign, sign, sign, sign) ) b11.next = ( False if (sel == Consts.IMM_U or sel == Consts.IMM_Z) else (instruction[20] if sel == Consts.IMM_UJ else (instruction[7] if sel == Consts.IMM_SB else sign)) ) b10_5.next = modbv(0)[6:] if (sel == Consts.IMM_U or sel == Consts.IMM_Z) else instruction[31:25] b4_1.next = ( modbv(0)[4:] if sel == Consts.IMM_U else ( instruction[12:8] if (sel == Consts.IMM_S or sel == Consts.IMM_SB) else (instruction[20:16] if sel == Consts.IMM_Z else instruction[25:21]) ) ) b0.next = ( instruction[7] if sel == Consts.IMM_S else (instruction[20] if sel == Consts.IMM_I else (instruction[15] if sel == Consts.IMM_Z else False)) ) @always_comb def imm_concat(): imm.next = concat(sign, b30_20, b19_12, b11, b10_5, b4_1, b0) return instances()
def MultShifter( shifted, data, direction, num ): WIDTH = len(data) MAX_SHIFT = 2**len(num) line_in_bits = [Signal(bool(0)) for k in range(WIDTH)] @always_comb def line_in_conn(): for k in range(WIDTH): line_in_bits[k].next = data[k] line_in_origin = ConcatSignal(*reversed(line_in_bits)) line_in_reversed = ConcatSignal(*line_in_bits) line_in = Signal(modbv(0)[WIDTH:]) @always_comb def line_in_mux(): if direction==LEFT: line_in.next = line_in_origin else: line_in.next = line_in_reversed line_out = Signal(modbv(0)[WIDTH:]) line_out_bits = [Signal(bool(0)) for k in range(WIDTH)] @always_comb def line_out_conn(): for k in range(WIDTH): line_out_bits[k].next = line_out[k] line_out_origin = ConcatSignal(*reversed(line_out_bits)) line_out_reversed = ConcatSignal(*line_out_bits) @always_comb def shifted_mux(): if direction==LEFT: shifted.next = line_out_origin else: shifted.next = line_out_reversed m = Signal(modbv(0)[WIDTH:]) @always_comb def num_to_pow(): temp = modbv(0)[WIDTH:] for k in range(WIDTH): if k == num: temp[k] = 1 m.next = temp @always_comb def shift(): if num > WIDTH - 1: line_out.next = 0 else: line_out.next = line_in * m return instances()
def __init__(self): self.dividend = Signal(modbv(0)[32:]) self.divisor = Signal(modbv(0)[32:]) self.divs = Signal(False) self.divu = Signal(False) self.active = Signal(False) self.ready = Signal(False) self.quotient = Signal(modbv(0)[32:]) self.remainder = Signal(modbv(0)[32:])
def __init__(self): self.input1 = Signal(modbv(0)[32:]) self.input2 = Signal(modbv(0)[32:]) self.cmd = Signal(modbv(0)[MultiplierOP.SZ_OP :]) self.enable = Signal(False) self.stall = Signal(False) self.kill = Signal(False) self.output = Signal(modbv(0)[64:]) self.active = Signal(False) self.ready = Signal(False)
def convert_to_verilog(args): clk = Signal(False) rst = Signal(False) imem_addr_o = Signal(modbv(0)[32:]) imem_dat_o = Signal(modbv(0)[32:]) imem_sel_o = Signal(modbv(0)[4:]) imem_cyc_o = Signal(False) imem_we_o = Signal(False) imem_stb_o = Signal(False) imem_dat_i = Signal(modbv(0)[32:]) imem_ack_i = Signal(False) imem_err_i = Signal(False) dmem_addr_o = Signal(modbv(0)[32:]) dmem_dat_o = Signal(modbv(0)[32:]) dmem_sel_o = Signal(modbv(0)[4:]) dmem_cyc_o = Signal(False) dmem_we_o = Signal(False) dmem_stb_o = Signal(False) dmem_dat_i = Signal(modbv(0)[32:]) dmem_ack_i = Signal(False) dmem_err_i = Signal(False) toHost = Signal(modbv(0)[32:]) toVerilog(CoreHDL, clk, rst, toHost, imem_addr_o, imem_dat_o, imem_sel_o, imem_cyc_o, imem_we_o, imem_stb_o, imem_dat_i, imem_ack_i, imem_err_i, dmem_addr_o, dmem_dat_o, dmem_sel_o, dmem_cyc_o, dmem_we_o, dmem_stb_o, dmem_dat_i, dmem_ack_i, dmem_err_i)
def __init__(self, A_WIDTH=10, D_WIDTH=8): """ Initializes the IO ports. """ self.clk = Signal(False) self.addr = Signal(modbv(0)[A_WIDTH:]) self.data_i = Signal(modbv(0)[D_WIDTH:]) self.data_o = Signal(modbv(0)[D_WIDTH:]) self.we = Signal(False)
def to_verilog(): ib_a = Signal(modbv(0)[4:]) ib_d = Signal(modbv(0)[8:]) db_a = Signal(modbv(0)[4:]) db_rw = Signal(bool(0)) db_dr = Signal(modbv(0)[8:]) db_dw = Signal(modbv(0)[8:]) clk = Signal(bool(0)) sc19 = SC19(ib_a, ib_d, db_a, db_rw, db_dr, db_dw, clk) sc19.convert(hdl='verilog')
def tag_flush_port_assign(): for i in range(WAYS): tfp_clk[i].next = clk_i tfp_addr[i].next = flush_addr tfp_data_i[i].next = modbv(0)[TAGMEM_WAY_WIDTH:] tfp_we[i].next = flush_we # connect to the LRU memory tag_lru_flush_port.clk.next = clk_i tag_lru_flush_port.addr.next = flush_addr tag_lru_flush_port.data_i.next = modbv(0)[TAG_LRU_WIDTH:] tag_lru_flush_port.we.next = flush_we
def flush_next_state(): n_flush_we.next = False n_flush_addr.next = flush_addr if state == dc_states.IDLE: if invalidate: n_flush_addr.next = modbv(-1)[SET_WIDTH:] elif state == dc_states.FLUSH1: n_flush_we.next = True elif state == dc_states.FLUSH2: n_flush_we.next = False n_flush_addr.next = flush_addr - modbv(1)[SET_WIDTH:]
def __init__(self): """ Initializes the IO ports. """ self.addr = Signal(modbv(0)[32:]) self.dat_o = Signal(modbv(0)[32:]) self.dat_i = Signal(modbv(0)[32:]) self.sel = Signal(modbv(0)[4:]) self.cyc = Signal(False) self.we = Signal(False) self.stb = Signal(False) self.ack = Signal(False) self.err = Signal(False)
def test(): in_ = Signal(modbv()[4:]) out = Signal(modbv()[7:]) segctrl = Decoder(out, in_) @instance def stimulus(): for x in range(16): in_.next = x print(out, in_) yield delay(10) return segctrl, stimulus
def convert_test(target): depth = 4 width = 4 dout = Signal(modbv(0)[width:]) din = Signal(modbv(0)[width:]) full = Signal(bool(0)) empty = Signal(bool(0)) push = Signal(bool(0)) clk = Signal(bool(0)) stack = Stack(dout, din, full, empty, push, clk, width=width, depth=depth) stack.convert(hdl=target)
def test_convert(hdl, clk_freq): rx = Signal(bool(0)) tx = Signal(bool(0)) rx_finish = Signal(bool(0)) tx_occupy = Signal(bool(0)) tx_start = Signal(bool(1)) rx_reg = Signal(modbv(0)[8:]) tx_reg = Signal(modbv(0b01010101)[8:]) clk = Signal(bool(0)) rst = Signal(bool(0)) baud_rate = 9600 inst = UART(rx, tx, rx_finish, tx_occupy, tx_start, rx_reg, tx_reg, clk, rst, baud_rate=baud_rate, clk_freq=clk_freq) inst.convert(hdl=hdl)
def RegisterFile(clk, portA, portB, writePort): """ The Register File (RF) module. 32 32-bit registers, with the register 0 hardwired to zero. :param clk: System clock :param portA: IO bundle (read port) :param portB: IO bundle (read port) :param writePort: IO bundle (write port) """ _registers = [Signal(modbv(0)[32:]) for ii in range(0, 32)] @always_comb def read(): """ Asynchronous read operation. """ portA.rd.next = _registers[portA.ra] if portA.ra != 0 else 0 portB.rd.next = _registers[portB.ra] if portB.ra != 0 else 0 @always(clk.posedge) def write(): """ Synchronous write operation. If the write address is zero, do nothing. """ if writePort.wa != 0 and writePort.we == 1: _registers[writePort.wa].next = writePort.wd return read, write
def Encrypt_StateUpdate128_1bit(clk, rst, state, plaintextbit, ks, ca, cb, ciphertextbit): state0 = Signal(modbv(0)[292:]) FBK128_inst = FBK128(state, ca, cb, ks, f) @always_comb def logic(): state0[292:290].next = state[292:290] state0[289:231].next = state[289:231] state0[230:194].next = state[230:194] state0[193:155].next = state[193:155] state0[154:108].next = state[154:108] state0[107: 62].next = state[107: 62] state0[ 61: 0].next = state[ 61: 0] state0[289].next = state[289] ^ state[235] ^ state[230] state0[230].next = state[230] ^ state[196] ^ state[193] state0[193].next = state[193] ^ state[160] ^ state[154] state0[154].next = state[154] ^ state[111] ^ state[107] state0[107].next = state[107] ^ state[ 66] ^ state[ 61] state0[ 61].next = state[ 61] ^ state[ 23] ^ state[ 0] @always_seq(clk.posedge, reset = rst) def stateUpdate(): state[292:].next = state0[293:1] state[292] = f ^ plaintextbit ciphertextbit = ks ^ plaintextbit return instances()
def icestick(clock, led, pmod, uart_tx, uart_rx): """ Lattice Icestick example """ glbl = Global(clock, None) gticks = glbl_timer_ticks(glbl, include_seconds=True) # get interfaces to the UART fifos fbustx = FIFOBus(width=8, size=8) fbusrx = FIFOBus(width=8, size=8) # get the UART comm from PC guart = uartlite(glbl, fbustx, fbusrx, uart_tx, uart_rx) @always_comb def beh_loopback(): fbusrx.rd.next = not fbusrx.empty fbustx.wr.next = not fbusrx.empty fbustx.wdata.next = fbusrx.rdata lcnt = Signal(modbv(0, min=0, max=4)) @always(clock.posedge) def beh_led_count(): if glbl.tick_sec: lcnt.next = lcnt + 1 led.next = (1 << lcnt) # system to test/interface # other stuff return instances()
def Oscillator(z, state, clock: Signal, output_freq: int, reset, sampling_freq: int): count = Signal(modbv(0, min=0, max=2**24)) inc = Signal(intbv(0, min=0, max=2**24)) @always_seq(clock.posedge, reset=reset) def output(): count.next = count + inc addr = count[24:12] if state == osc_state.SINE: z.next = sine[addr] elif state == osc_state.SQUARE: z.next = square[addr] elif state == osc_state.TRIANGLE: z.next = triangle[addr] elif state == osc_state.SAWTOOTH: z.next = sawtooth[addr] elif state == osc_state.PWM: pass elif state == osc_state.NOISE: pass @always_comb def increment(): inc_val = intbv(int(n_samps * output_freq * 2**12 / sampling_freq), min=0, max=2**24) inc.val = inc_val return output
def Test(): code = Signal(modbv(0)[2:]) valid = Signal(bool(0)) in_ = Signal(modbv(0)[4:]) encoder = PriorityEncoder(code, valid, in_) @instance def stimulus(): print('code\tvalid\tin') for k in range(16): in_.next = k yield delay(10) print(code, valid, f'{int(in_):04b}', sep='\t') return instances()
def src_a_mux_output(): alu_src_a.next = modbv(0)[XPR_LEN:] if src_a_sel == SRC_A_RS1: alu_src_a.next = PC_DX elif src_a_sel == SRC_A_PC: alu_src_a.next = rs1_data
def decomp_proc(): """ verilator lint_off WIDTH """ shift[0].next = binary_i for i in range(NBIT): thousand = shift[i][NBIT + 16:NBIT + 12] + 3 hundred = shift[i][NBIT + 12:NBIT + 8] + 3 ten = shift[i][NBIT + 8:NBIT + 4] + 3 one = shift[i][NBIT + 4:NBIT] + 3 shift[i + 1].next = hdl.concat( shift[i][NBIT + 16:NBIT + 12] if shift[i][NBIT + 16:NBIT + 12] < 5 else hdl.modbv(thousand)[4:], shift[i][NBIT + 12:NBIT + 8] if shift[i][NBIT + 12:NBIT + 8] < 5 else hdl.modbv(hundred)[4:], shift[i][NBIT + 8:NBIT + 4] if shift[i][NBIT + 8:NBIT + 4] < 5 else hdl.modbv(ten)[4:], shift[i][NBIT + 4:NBIT] if shift[i][NBIT + 4:NBIT] < 5 else hdl.modbv(one)[4:], shift[i][NBIT:]) << 1 """ verilator lint_on WIDTH """
def generate_inputs(): for a in range(16): for b in range(16): # Asignar valores a los puertos de entrada A.next = a B.next = b for op in range(16): OP.next = op # asignar operación yield hdl.delay( 1 ) # esperar una unidad de tiempo para que ejecute el simulador. fs if op == 0: assert result == hdl.modbv( A + B)[4:], "Error ADD. A = {0}, B = {1}".format( hex(A), hex(B)) elif op == 1: assert result == hdl.modbv( A - B)[4:], "Error SUB. A = {0}, B = {1}".format( hex(A), hex(B)) elif op == 2: assert result == A & B, "Error AND. A = {0}, B = {1}".format( hex(A), hex(B)) elif op == 3: assert result == A | B, "Error OR. A = {0}, B = {1}".format( hex(A), hex(B)) elif op == 4: assert result == A ^ B, "Error XOR. A = {0}, B = {1}".format( hex(A), hex(B)) elif op == 5: assert result == A, "Error A" elif op == 6: assert result == B, "Error B" elif op == 7: assert result == hdl.modbv(-A)[4:], "Error -A" elif op == 8: assert result == hdl.modbv(-B)[4:], "Error -B" elif op == 9: assert result == ~A, "Error ~A" elif op == 10: assert result == ~B, "Error ~B" else: assert result == 0, "Error UNDEFINED OP: salida no es 0." assert invalid == 1, "Error UNDEFINED OP: invalid output no detectada." raise hdl.StopSimulation
def test(): op.next = ALU_OP_ADD yield delay(10) assert out == modbv(val1 + val2)[XPR_LEN:] op.next = ALU_OP_SLL yield delay(10) assert out == modbv(val1 << shamt)[XPR_LEN:] op.next = ALU_OP_XOR yield delay(10) assert out == modbv(val1 ^ shamt)[XPR_LEN:] op.next = ALU_OP_OR yield delay(10) assert out == modbv(val1 | shamt)[XPR_LEN:] op.next = ALU_OP_AND yield delay(10) assert out == modbv(val1 & shamt)[XPR_LEN:] op.next = ALU_OP_SRL yield delay(10) assert out == modbv(in1.val >> shamt)[XPR_LEN:] op.next = ALU_OP_SEQ yield delay(10) assert out == (val1 == val2) op.next = ALU_OP_SNE yield delay(10) assert out == (val1 != val2) op.next = ALU_OP_SUB yield delay(10) assert out == modbv(val1 - val2)[XPR_LEN:] op.next = ALU_OP_SRA yield delay(10) assert out == modbv(val1 >> shamt)[XPR_LEN:] op.next = ALU_OP_SLT yield delay(10) assert out == (val1 < val2) op.next = ALU_OP_SGE yield delay(10) assert out == (val1 >= val2) op.next = ALU_OP_SLTU yield delay(10) assert out == (in1.val < in2.val) op.next = ALU_OP_SGEU yield delay(10) assert out == (in1.val >= in2.val)
def convert_gray_inc_reg(hdl, width=8): graycnt = Signal(modbv(0)[width:]) enable = Signal(bool()) clock = Signal(bool()) reset = ResetSignal(0, active=0, isasync=True) inst = gray_inc_reg(graycnt, enable, clock, reset, width) inst.convert(hdl)
def __init__(self, pins, iostandard): self.pins = Pins(pins) self.iostandard = IOStandard(iostandard) npins = len(self.pins) if npins > 1: super().__init__(hdl.modbv(0)[len(self.pins):]) else: super().__init__(False)
def fifo_mem_wrapper(clock, reset, datain, div, dataout, dorq): write_addr = Signal(modbv(0)[8:0]) read_addr = Signal(modbv(0)[8:0]) wad = Signal(intbv(0)[8:0]) mem_inst = fifo_mem(clock, div, datain, write_addr, clock, dorq, dataout, read_addr, wad) @always_seq(clock.posedge, reset=reset) def beh_addr(): if div: write_addr.next = write_addr + 1 if dorq: read_addr.next = read_addr + 1 return myhdl.instances()
def test_pc_mux(): PC_src_sel = Signal(modbv(0)[PC_SRC_SEL_WIDTH:]) inst_DX = Signal(modbv(randint(0, (1 << INST_WIDTH) - 1))[INST_WIDTH:]) rs1_data, PC_IF, PC_DX, handler_PC, epc = [Signal(modbv(randint(0, (1 << XPR_LEN) - 1))[XPR_LEN:]) for _ in range(5)] PC_PIF = Signal(modbv(0)[XPR_LEN:]) pc_mux_inst = PC_mux(PC_src_sel, inst_DX, rs1_data, PC_IF, PC_DX, handler_PC, epc, PC_PIF) pc_mux_inst.convert(hdl='Verilog') imm_b = concat(*[inst_DX[31] for _ in range(20)], inst_DX[7], inst_DX[31:25], inst_DX[12:8], False) jal_offset = concat(*[inst_DX[31] for _ in range(12)], inst_DX[20:12], inst_DX[20], inst_DX[31:25], inst_DX[25:21], False) jalr_offset = concat(*[inst_DX[31] for _ in range(21)], inst_DX[31:21], False) @instance def test(): PC_src_sel.next = PC_JAL_TARGET yield delay(10) assert PC_PIF == modbv(PC_DX + jal_offset)[XPR_LEN:] PC_src_sel.next = PC_JALR_TARGET yield delay(10) assert PC_PIF == modbv(rs1_data + jalr_offset)[XPR_LEN:] PC_src_sel.next = PC_BRANCH_TARGET yield delay(10) assert PC_PIF == modbv(PC_DX + imm_b)[XPR_LEN:] PC_src_sel.next = PC_REPLAY yield delay(10) assert PC_PIF == PC_IF PC_src_sel.next = PC_HANDLER yield delay(10) assert PC_PIF == handler_PC PC_src_sel.next = PC_EPC yield delay(10) assert PC_PIF == epc PC_src_sel.next = PC_PLUS_FOUR yield delay(10) assert PC_PIF == modbv(PC_IF + 4)[XPR_LEN:] return pc_mux_inst, test
def gray_inc(graycnt, enable, clock, reset, width): bincnt = Signal(modbv(0)[width:]) inc_0 = inc(bincnt, enable, clock, reset) bin2gray_0 = bin2gray(B=bincnt, G=graycnt) return inc_0, bin2gray_0
class CSRCMD: """ CSR commands. The CSR_READ command is for those cases when the 'rs1' field is zero. """ SZ_CMD = 3 CSR_IDLE = 0 CSR_READ = 4 CSR_WRITE = 5 CSR_SET = 6 CSR_CLEAR = 7 _CSR_IDLE = modbv(0)[SZ_CMD:] _CSR_READ = modbv(4)[SZ_CMD:] _CSR_WRITE = modbv(5)[SZ_CMD:] _CSR_SET = modbv(6)[SZ_CMD:] _CSR_CLEAR = modbv(7)[SZ_CMD:]
def _priv_stack(): """ The priviledge mode stack. - At reset: machine mode. - Exception: shift stack to the left, enter machine mode. - Eret: shift stack to the right. Set next mode to User leve. """ if rst: priv_stack.next = 0b000110 elif wen_internal & (rw.addr == CSRAddressMap.CSR_ADDR_MSTATUS): priv_stack.next = wdata_aux[6:0] elif exc_io.exception: # All exceptions to machine mode priv_stack.next = concat(priv_stack[3:0], modbv(0b11)[2:], False) elif exc_io.eret: priv_stack.next = concat(modbv(0)[2:], True, priv_stack[6:3])
def CalcStack(data_out, data_in, full, empty, op, op_success, offset, clk, posedge=True, width=8, depth=128): if posedge: edge = clk.posedge else: edge = clk.negedge mem = [Signal(intbv(0)[width:]) for i in range(depth)] pointer = Signal(modbv(0, min=0, max=depth)) @always_seq(edge, reset=None) def operate(): # print('mem:', mem) if op == STACK_OP.PUSH: if not full: if pointer == depth - 1: full.next = 1 if empty: empty.next = 0 mem[pointer].next = data_in pointer.next = pointer + 1 op_success.next = 1 else: op_success.next = 0 elif op == STACK_OP.POP: if not empty: if pointer == 1: empty.next = 1 if full: full.next = 0 data_out.next = mem[pointer - 1] pointer.next = pointer - 1 op_success.next = 1 else: op_success.next = 0 elif op == STACK_OP.UADD: if pointer >= 2 or full: mem[pointer - 2].next = mem[pointer - 2] + mem[pointer - 1] pointer.next = pointer - 1 op_success.next = 1 else: op_success.next = 0 elif op == STACK_OP.IDLE: pass else: pass return instances()
def test_hasti_bridge(): haddr, core_mem_addr = [ Signal(modbv(0)[HASTI_ADDR_WIDTH:]) for _ in range(2) ] hsize, core_mem_size = [ Signal(modbv(0)[HASTI_SIZE_WIDTH:]) for _ in range(2) ] hwrite, hmastlock, hready, core_mem_wn, core_mem_wen, core_mem_en, core_mem_wait, core_badmem_e = [ Signal(False) for _ in range(8) ] hburst = Signal(modbv(0)[HASTI_BURST_WIDTH:]) hprot = Signal(modbv(0)[HASTI_PROT_WIDTH:]) htrans = Signal(modbv(0)[HASTI_TRANS_WIDTH:]) hwdata, hrdata, core_mem_wdata_delayed, core_mem_rdata = [ Signal(modbv(0)[HASTI_BUS_WIDTH:]) for _ in range(4) ] hresp = Signal(modbv(0)[HASTI_RESP_WIDTH:]) hasti_bridge_inst = hasti_bridge(haddr, hwrite, hsize, hburst, hmastlock, hprot, htrans, hwdata, core_mem_rdata, core_mem_wait, core_badmem_e, hrdata, hready, hresp, core_mem_en, core_mem_wen, core_mem_size, core_mem_addr, core_mem_wdata_delayed) hasti_bridge_inst.convert(hdl='Verilog')
def tb_pwm(): length = 4 we = Signal(bool(0)) bus_in = Signal(modbv(0)[length:]) bus_out = Signal(modbv(0)[length:]) output = Signal(bool(0)) cnt_enable = Signal(bool(1)) clock = Signal(bool(0)) reset = ResetSignal(0, active=1, isasync=False) clk_driver = ClkDriver(clock) pwm_inst = pwm(we, bus_in, bus_out, output, cnt_enable, clock, reset, length) we_temp = Signal(bool(0)) @always_seq(clock.posedge, reset=reset) def seq(): we.next = not we and we_temp @instance def stimulus(): i = 0 k = 2**length #print k reset.next = True yield delay(40) reset.next = False yield delay(40) while i < k: #print i bus_in.next = i we_temp.next = True yield delay(40) we_temp.next = False yield delay(20 * k * 4) i = i + 1 return instances()
def modOrInt(min, max, mod): if mod: return modbv(0 if default_value is None else default_value, min=min, max=max) else: return intbv(0 if default_value is None else default_value, min=min, max=max)
def convert_int_to_float(target): EXPONENT_WIDTH = 8 FRACTION_WIDTH = 23 EXPONENT_BIAS = 127 INT_WIDTH = 6 float_sig = Signal(modbv(0)[(1+EXPONENT_WIDTH+FRACTION_WIDTH):]) int_sig = Signal(modbv(0)[INT_WIDTH:]) convertor = IntToFloat( float_sig, int_sig, exponent_width=EXPONENT_WIDTH, fraction_width=FRACTION_WIDTH, exponent_bias=EXPONENT_BIAS) convertor.convert(hdl=target)
def assignments(): final_fetch.next = (refill_addr[BLOCK_WIDTH - 2:] == modbv( -1)[BLOCK_WIDTH - 2:]) and mem_wbm.ack_i and mem_wbm.stb_o and mem_wbm.cyc_o lru_select.next = lru_pre current_lru.next = lru_out access_lru.next = ~miss_w busy.next = state != ic_states.IDLE final_flush.next = flush_addr == 0
def createModbv(init, width): """ Wrapper to create unsigned bit vectors. Args: - init: Initial value. - width: Signal width. """ assert width >= 1, "Invalid width = {0}".format(width) return hdl.modbv(init)[width:]
def update_addr_fsm(): if rst_i: dc_update_addr.next = 0 else: if state == dc_states.READ or state == dc_states.WRITE: if miss and not dirty: dc_update_addr.next = concat(cpu_wbs.addr_i[LIMIT_WIDTH:BLOCK_WIDTH], modbv(0)[BLOCK_WIDTH - 2:]) elif miss and dirty: dc_update_addr.next = concat(tag_entry, cpu_wbs.addr_i[WAY_WIDTH:2]) elif state == dc_states.FLUSH2: if dirty: dc_update_addr.next = concat(tag_entry, modbv(0)[WAY_WIDTH - 2:]) elif state == dc_states.EVICTING or state == dc_states.FETCH or state == dc_states.FLUSH3: if final_access: dc_update_addr.next = concat(cpu_wbs.addr_i[LIMIT_WIDTH:BLOCK_WIDTH], modbv(0)[BLOCK_WIDTH - 2:]) elif mem_wbm.ack_i and mem_wbm.stb_o: dc_update_addr.next = dc_update_addr + modbv(1)[BLOCK_WIDTH - 2:] else: dc_update_addr.next = 0
def testbench_qr(): a, b, c, d = [Signal(modbv(0, min=0, max=2**32)) for _ in range(4)] ao, bo, co, do = [Signal(modbv(0, min=0, max=2**32)) for _ in range(4)] q1 = core.q_round(a, b, c, d, ao, bo, co, do) @instance def stimulus(): for _ in range(100): calc = [random.randrange(2**32) for _ in range(4)] a.next, b.next, c.next, d.next = calc quarter_round(calc, 0, 1, 2, 3) yield delay(10) print('Result: ' + ('%08X' * 4) % (a, b, c, d)) print('Should: ' + ('%08X' * 4) % tuple(calc)) assert (calc == [ao, bo, co, do]) return q1, stimulus
def _custom_source(output, clock): counter = modbv(0, min=0, max=mod_max) reset = ResetSignal(bool(0), active=1, async=False) @always_seq(clock.posedge, reset=reset) def custom(): counter[:] = counter + 1 output.next = counter return custom
def IMMGen(sel, instruction, imm): """ Generate the immediate values. :param sel: Select the type of instruction/immediate :param instruction: Current instruction :param imm: A 32-bit immediate value """ sign = Signal(False) b30_20 = Signal(modbv(0)[11:]) b19_12 = Signal(modbv(0)[8:]) b11 = Signal(False) b10_5 = Signal(modbv(0)[6:]) b4_1 = Signal(modbv(0)[4:]) b0 = Signal(False) @always_comb def _sign(): sign.next = False if sel == Consts.IMM_Z else instruction[31] @always_comb def rtl(): b30_20.next = instruction[31:20] if sel == Consts.IMM_U else concat(sign, sign, sign, sign, sign, sign, sign, sign, sign, sign, sign) b19_12.next = instruction[20:12] if (sel == Consts.IMM_U or sel == Consts.IMM_UJ) else concat(sign, sign, sign, sign, sign, sign, sign, sign) b11.next = (False if (sel == Consts.IMM_U or sel == Consts.IMM_Z) else (instruction[20] if sel == Consts.IMM_UJ else (instruction[7] if sel == Consts.IMM_SB else sign))) b10_5.next = modbv(0)[6:] if (sel == Consts.IMM_U or sel == Consts.IMM_Z) else instruction[31:25] b4_1.next = (modbv(0)[4:] if sel == Consts.IMM_U else (instruction[12:8] if (sel == Consts.IMM_S or sel == Consts.IMM_SB) else (instruction[20:16] if sel == Consts.IMM_Z else instruction[25:21]))) b0.next = (instruction[7] if sel == Consts.IMM_S else (instruction[20] if sel == Consts.IMM_I else (instruction[15] if sel == Consts.IMM_Z else False))) @always_comb def imm_concat(): imm.next = concat(sign, b30_20, b19_12, b11, b10_5, b4_1, b0) return instances()
def rtl(): if io.function == ALUOp.OP_ADD: io.output.next = io.input1 + io.input2 elif io.function == ALUOp.OP_SLL: io.output.next = io.input1 << io.input2[5:0] elif io.function == ALUOp.OP_XOR: io.output.next = io.input1 ^ io.input2 elif io.function == ALUOp.OP_SRL: io.output.next = io.input1 >> io.input2[5:0] elif io.function == ALUOp.OP_OR: io.output.next = io.input1 | io.input2 elif io.function == ALUOp.OP_AND: io.output.next = io.input1 & io.input2 elif io.function == ALUOp.OP_SUB: io.output.next = io.input1 - io.input2 elif io.function == ALUOp.OP_SRA: io.output.next = io.input1.signed() >> io.input2[5:0] elif io.function == ALUOp.OP_SLT: io.output.next = concat( modbv(0)[31:], io.input1.signed() < io.input2.signed()) elif io.function == ALUOp.OP_SLTU: io.output.next = concat(modbv(0)[31:], io.input1 < io.input2) elif io.function == ALUOp.OP_MUL: io.output.next = mult_l elif io.function == ALUOp.OP_MULH: io.output.next = mult_h elif io.function == ALUOp.OP_MULHSU: io.output.next = mult_h elif io.function == ALUOp.OP_MULHU: io.output.next = mult_h elif io.function == ALUOp.OP_DIV: io.output.next = quotient elif io.function == ALUOp.OP_DIVU: io.output.next = quotient elif io.function == ALUOp.OP_REM: io.output.next = remainder elif io.function == ALUOp.OP_REMU: io.output.next = remainder else: io.output.next = 0
def Test(direction): rx = Signal(bool(0)) tx = Signal(bool(1)) rx_finish = Signal(bool(0)) tx_occupy = Signal(bool(0)) tx_start = Signal(bool(1)) rx_reg = Signal(modbv(0)[8:]) tx_reg = Signal(modbv(0b11010100)[8:]) clk = Signal(bool(0)) rst = Signal(bool(0)) baud_rate = 9600 factor = 16 clk_freq = 9600*factor inst = UART(rx, tx, rx_finish, tx_occupy, tx_start, rx_reg, tx_reg, clk, rst, baud_rate=baud_rate, clk_freq=clk_freq) if direction == 'tx': @instance def stimulus(): rx.next = 1 for k in range(1000): yield delay(10) clk.next = not clk else: @instance def stimulus(): rx.next = 1 for k in range(factor): clk.next = not clk yield delay(10) clk.next = not clk yield delay(10) for k in range(200): if k % factor == 0: rx.next = not rx clk.next = not clk yield delay(10) clk.next = not clk yield delay(10) return instances()
def clock_divider(clk, clk_out, in_freq=50*10**6, out_freq=1): max_count = int(in_freq / (out_freq*2)) count = Signal(modbv(0, min=0, max=2**ceil(log2(max_count)))) @always(clk.posedge) def logic(): count.next = count + 1 if count.next > max_count: count.next = 0 clk_out.next = not clk_out return logic