/ test / func_blocks / fu / fpu / test_add_sub.py
test_add_sub.py
  1  from coreblocks.func_blocks.fu.fpu.fpu_add_sub import *
  2  from coreblocks.func_blocks.fu.fpu.fpu_common import FPUParams, RoundingModes
  3  from test.func_blocks.fu.fpu.fpu_test_common import FPUTester, python_to_float
  4  from test.func_blocks.fu.fpu.add_sub_test_cases import *
  5  from transactron.testing import *
  6  from amaranth import *
  7  import random
  8  import struct
  9  
 10  
 11  class TestAddSub(TestCaseWithSimulator):
 12      def test_manual(self):
 13          params = FPUParams(sig_width=24, exp_width=8)
 14          tester = FPUTester(params)
 15          m = SimpleTestCircuit(FPUAddSubModule(fpu_params=params))
 16  
 17          async def python_float_test(sim: TestbenchContext, request_adapter: TestbenchIO):
 18              seed = 42
 19              test_runs = 20
 20              random.seed(seed)
 21  
 22              for i in range(test_runs):
 23                  input_dict = {}
 24                  p_float_1 = python_to_float(random.uniform(0, 3.4028235 * (10**38)))
 25                  p_float_2 = python_to_float(random.uniform(0, 3.4028235 * (10**38)))
 26                  if i < test_runs / 2:
 27                      input_dict["operation"] = 0
 28                      result = python_to_float(p_float_1 + p_float_2)
 29                  else:
 30                      input_dict["operation"] = 1
 31                      result = python_to_float(p_float_1 - p_float_2)
 32                  hex_1 = hex(struct.unpack("<I", struct.pack("<f", p_float_1))[0])
 33                  hex_2 = hex(struct.unpack("<I", struct.pack("<f", p_float_2))[0])
 34                  hex_result = hex(struct.unpack("<I", struct.pack("<f", result))[0])
 35  
 36                  input_dict["op_1"] = tester.converter.from_hex(hex_1)
 37                  input_dict["op_2"] = tester.converter.from_hex(hex_2)
 38                  input_dict["rounding_mode"] = RoundingModes.ROUND_NEAREST_EVEN
 39  
 40                  result = tester.converter.from_hex(hex_result)
 41                  resp = await request_adapter.call(sim, input_dict)
 42  
 43                  assert result["sign"] == resp["sign"]
 44                  assert result["exp"] == resp["exp"]
 45                  assert result["sig"] == resp["sig"]
 46  
 47          async def test_process(sim: TestbenchContext):
 48              await python_float_test(sim, m.add_sub_request)
 49              await tester.run_test_set(
 50                  nc_add_rtne,
 51                  nc_add_rtne_resp,
 52                  {"rounding_mode": RoundingModes.ROUND_NEAREST_EVEN, "operation": 0},
 53                  sim,
 54                  m.add_sub_request,
 55              )
 56  
 57              await tester.run_test_set(
 58                  nc_add_rtna,
 59                  nc_add_rtna_resp,
 60                  {"rounding_mode": RoundingModes.ROUND_NEAREST_AWAY, "operation": 0},
 61                  sim,
 62                  m.add_sub_request,
 63              )
 64  
 65              await tester.run_test_set(
 66                  nc_add_up,
 67                  nc_add_up_resp,
 68                  {"rounding_mode": RoundingModes.ROUND_UP, "operation": 0},
 69                  sim,
 70                  m.add_sub_request,
 71              )
 72  
 73              await tester.run_test_set(
 74                  nc_add_down,
 75                  nc_add_down_resp,
 76                  {"rounding_mode": RoundingModes.ROUND_DOWN, "operation": 0},
 77                  sim,
 78                  m.add_sub_request,
 79              )
 80  
 81              await tester.run_test_set(
 82                  nc_add_zero,
 83                  nc_add_zero_resp,
 84                  {"rounding_mode": RoundingModes.ROUND_ZERO, "operation": 0},
 85                  sim,
 86                  m.add_sub_request,
 87              )
 88  
 89              await tester.run_test_set(
 90                  nc_sub_rtne,
 91                  nc_sub_rtne_resp,
 92                  {"rounding_mode": RoundingModes.ROUND_NEAREST_EVEN, "operation": 1},
 93                  sim,
 94                  m.add_sub_request,
 95              )
 96  
 97              await tester.run_test_set(
 98                  nc_sub_rtna,
 99                  nc_sub_rtna_resp,
100                  {"rounding_mode": RoundingModes.ROUND_NEAREST_AWAY, "operation": 1},
101                  sim,
102                  m.add_sub_request,
103              )
104  
105              await tester.run_test_set(
106                  nc_sub_up,
107                  nc_sub_up_resp,
108                  {"rounding_mode": RoundingModes.ROUND_UP, "operation": 1},
109                  sim,
110                  m.add_sub_request,
111              )
112  
113              await tester.run_test_set(
114                  nc_sub_down,
115                  nc_sub_down_resp,
116                  {"rounding_mode": RoundingModes.ROUND_DOWN, "operation": 1},
117                  sim,
118                  m.add_sub_request,
119              )
120  
121              await tester.run_test_set(
122                  nc_sub_zero,
123                  nc_sub_zero_resp,
124                  {"rounding_mode": RoundingModes.ROUND_ZERO, "operation": 1},
125                  sim,
126                  m.add_sub_request,
127              )
128  
129              await tester.run_test_set(
130                  edge_cases_add,
131                  edge_cases_add_resp,
132                  {"rounding_mode": RoundingModes.ROUND_NEAREST_EVEN, "operation": 0},
133                  sim,
134                  m.add_sub_request,
135              )
136  
137              await tester.run_test_set(
138                  edge_cases_sub,
139                  edge_cases_sub_resp,
140                  {"rounding_mode": RoundingModes.ROUND_NEAREST_EVEN, "operation": 1},
141                  sim,
142                  m.add_sub_request,
143              )
144  
145              await tester.run_test_set(
146                  edge_cases_sub_down,
147                  edge_cases_sub_down_resp,
148                  {"rounding_mode": RoundingModes.ROUND_DOWN, "operation": 1},
149                  sim,
150                  m.add_sub_request,
151              )
152              await tester.run_test_set(
153                  edge_cases_sub_up,
154                  edge_cases_sub_up_resp,
155                  {"rounding_mode": RoundingModes.ROUND_UP, "operation": 1},
156                  sim,
157                  m.add_sub_request,
158              )
159  
160          with self.run_simulation(m) as sim:
161              sim.add_testbench(test_process)