code wiki / _hdl_build / nx_rtype_control.nx

nx_rtype_control.nx source

↩ module page · 56 lines · 3111 B

1// nx_rtype_control.nx -- sink-based R-type (opcode OP) decode->execute CONTROL: maps funct3/funct7 2// to an ALU op code, as gates. This is the glue between the decoder and the ALU -- the missing piece 3// for top-level CPU netlist composition. Mirrors the OP branch of nx_rv64im_sim_alu_select 4// (rv64im_min_sim.nx): funct3 selects the base op (funct7==0x20 picks SUB/SRA for f3 0/5), and 5// funct7==0x01 overlays the M-extension (mul/mulh/.../div/.../rem). MUX(sel, if_true, if_false) per 6// gsim. Flat idiom. Verified standalone by nx_rtype_control_mem_test (exhaustive over funct3 x funct7). 7// license_tier: ORIGINAL expect_exit: 0 8import "nx_cell_sink.nx" 9import "rv64im_min_alu.nx" // NX_RV64IM_ALU_* op codes 10 11func _rc_c(k: *NxCellSink, v: i64) -> i64 { return nx_sink_const(k, 64, v) } 12func _rc_eq(k: *NxCellSink, a: i64, cval: i64) -> i64 { 13 let c: i64 = nx_sink_const(k, 64, cval) 14 return nx_sink_cell(k, NX_GATE_KIND_EQ, 1, a, c, 0 - 1, 2) 15} 16// sel ? t : f 17func _rc_mux(k: *NxCellSink, sel: i64, t: i64, f: i64) -> i64 { 18 return nx_sink_cell(k, NX_GATE_KIND_MUX, 64, sel, t, f, 3) 19} 20 21// returns the ALU-op net for an R-type OP instruction given funct3/funct7 net ids. 22func nx_rtype_op_aluop_build(k: *NxCellSink, n_f3: i64, n_f7: i64) -> i64 { 23 let f7eq20: i64 = _rc_eq(k, n_f7, 32) // 0x20 -> SUB/SRA variant 24 let f7eq1: i64 = _rc_eq(k, n_f7, 1) // 0x01 -> M extension 25 let f3eq1: i64 = _rc_eq(k, n_f3, 1) 26 let f3eq2: i64 = _rc_eq(k, n_f3, 2) 27 let f3eq3: i64 = _rc_eq(k, n_f3, 3) 28 let f3eq4: i64 = _rc_eq(k, n_f3, 4) 29 let f3eq5: i64 = _rc_eq(k, n_f3, 5) 30 let f3eq6: i64 = _rc_eq(k, n_f3, 6) 31 let f3eq7: i64 = _rc_eq(k, n_f3, 7) 32 33 // ----- base (non-M) op ----- 34 let add_or_sub: i64 = _rc_mux(k, f7eq20, _rc_c(k, NX_RV64IM_ALU_SUB), _rc_c(k, NX_RV64IM_ALU_ADD)) 35 let srl_or_sra: i64 = _rc_mux(k, f7eq20, _rc_c(k, NX_RV64IM_ALU_SRA), _rc_c(k, NX_RV64IM_ALU_SRL)) 36 var base: i64 = add_or_sub // f3==0 default 37 base = _rc_mux(k, f3eq1, _rc_c(k, NX_RV64IM_ALU_SLL), base) 38 base = _rc_mux(k, f3eq2, _rc_c(k, NX_RV64IM_ALU_SLT), base) 39 base = _rc_mux(k, f3eq3, _rc_c(k, NX_RV64IM_ALU_SLTU), base) 40 base = _rc_mux(k, f3eq4, _rc_c(k, NX_RV64IM_ALU_XOR), base) 41 base = _rc_mux(k, f3eq5, srl_or_sra, base) 42 base = _rc_mux(k, f3eq6, _rc_c(k, NX_RV64IM_ALU_OR), base) 43 base = _rc_mux(k, f3eq7, _rc_c(k, NX_RV64IM_ALU_AND), base) 44 45 // ----- M-extension op (funct7 == 0x01) ----- 46 var mop: i64 = _rc_c(k, NX_RV64IM_ALU_MUL) // f3==0 default 47 mop = _rc_mux(k, f3eq1, _rc_c(k, NX_RV64IM_ALU_MULH), mop) 48 mop = _rc_mux(k, f3eq2, _rc_c(k, NX_RV64IM_ALU_MULHSU), mop) 49 mop = _rc_mux(k, f3eq3, _rc_c(k, NX_RV64IM_ALU_MULHU), mop) 50 mop = _rc_mux(k, f3eq4, _rc_c(k, NX_RV64IM_ALU_DIV), mop) 51 mop = _rc_mux(k, f3eq5, _rc_c(k, NX_RV64IM_ALU_DIVU), mop) 52 mop = _rc_mux(k, f3eq6, _rc_c(k, NX_RV64IM_ALU_REM), mop) 53 mop = _rc_mux(k, f3eq7, _rc_c(k, NX_RV64IM_ALU_REMU), mop) 54 55 return _rc_mux(k, f7eq1, mop, base) // f7==1 ? M-op : base 56}