perf(test/lab4): 增强了 lab4 的测试数据 #1

Merged
ppg69fuwb merged 1 commits from hdu23150919/riscv-lab:testcasefix into main 10 months ago

File diff suppressed because it is too large Load Diff

@ -4,7 +4,7 @@ import os
random.seed(0)
reg = [f"x{i}" for i in range(32)]
# 定义R型运算类指令
# Define R-type arithmetic instructions
inst_reg = [
"add",
"sub",
@ -62,15 +62,13 @@ file_name = "test"
mem_start = 0x80200000
mem_end = 0x80210000
# 自动生成R型指令测试样例1000个输出到file_name文件中
# 新建build文件夹存放生成的文件
# 初始化寄存器状态0表示可用
# Initialize register status: 0 means available.
reg_status = {r: 0 for r in reg}
def get_available_reg(reg, reg_status):
available_regs = [r for r, status in reg_status.items() if status == 0]
if not available_regs: # 如果没有可用的寄存器则返回x0
if not available_regs: # If no register available, return x0.
return reg[0]
return random.choice(available_regs)
@ -78,7 +76,7 @@ def get_available_reg(reg, reg_status):
def update_reg_status(reg_status):
for r in reg_status:
if reg_status[r] > 0:
reg_status[r] -= 1 # 减少计数,向可用状态靠近
reg_status[r] -= 1 # Countdown to register availability
def test_reg_inst(insts=inst_reg):
@ -87,8 +85,8 @@ def test_reg_inst(insts=inst_reg):
rs1 = get_available_reg(reg, reg_status)
rs2 = get_available_reg(reg, reg_status)
f.write(f"\t{inst} {rd}, {rs1}, {rs2}\n")
reg_status[rd] = 4 # 解决数据冲突
update_reg_status(reg_status) # 更新寄存器状态
reg_status[rd] = 4 # Delay to avoid data hazard
update_reg_status(reg_status)
def test_imm_inst():
@ -102,8 +100,8 @@ def test_imm_inst():
else:
imm = random.randint(-(2**11), 2**11 - 1)
f.write(f"\t{inst} {rd}, {rs1}, {imm}\n")
reg_status[rd] = 4 # 解决数据冲突
update_reg_status(reg_status) # 更新寄存器状态
reg_status[rd] = 4
update_reg_status(reg_status)
def test_lui_inst():
@ -111,8 +109,8 @@ def test_lui_inst():
rd = get_available_reg(reg, reg_status)
imm = random.randint(0, 2**20 - 1)
f.write(f"\t{inst} {rd}, {imm}\n")
reg_status[rd] = 4 # 解决数据冲突
update_reg_status(reg_status) # 更新寄存器状态
reg_status[rd] = 4
update_reg_status(reg_status)
def wait_gpr(index):
@ -130,7 +128,7 @@ def insert_nop(n=3):
def test_lb():
f.write("\taddiw x1, x0, 1025\n")
insert_nop()
f.write("\tslli x1, x1, 0x15\n") # x1=0x80200000
f.write("\tslli x1, x1, 0x15\n") # x1 = 0x80200000
insert_nop()
rd = get_available_reg(reg, reg_status)
while rd == "x1":
@ -139,82 +137,183 @@ def test_lb():
imm = random.randint(-(2**11), 2**11 - 1)
f.write(f"\tsb {rd}, {imm}({rs1})\n")
f.write(f"\tlb {rd}, {imm}({rs1})\n")
reg_status[rd] = 4 # 解决数据冲突
update_reg_status(reg_status) # 更新寄存器状态
reg_status[rd] = 4
update_reg_status(reg_status)
rd = get_available_reg(reg, reg_status)
while rd == "x1":
rd = get_available_reg(reg, reg_status)
f.write(f"\tlbu {rd}, {imm}({rs1})\n")
reg_status[rd] = 4 # 解决数据冲突
update_reg_status(reg_status) # 更新寄存器状态
reg_status[rd] = 4
update_reg_status(reg_status)
def test_lh():
f.write("\taddiw x1, x0, 1025\n")
insert_nop()
f.write("\tslli x1, x1, 0x15\n") # x1=0x80200000
f.write("\tslli x1, x1, 0x15\n") # x1 = 0x80200000
insert_nop()
rd = get_available_reg(reg, reg_status)
while rd == "x1":
rd = get_available_reg(reg, reg_status)
rs1 = "x1"
# Align immediate for halfword access (even address)
imm = random.randint(-(2**11), 2**11 - 1) & 0xFFFFFFFFFFFFFFFE
f.write(f"\tsh {rd}, {imm}({rs1})\n")
f.write(f"\tlh {rd}, {imm}({rs1})\n")
reg_status[rd] = 4 # 解决数据冲突
update_reg_status(reg_status) # 更新寄存器状态
reg_status[rd] = 4
update_reg_status(reg_status)
rd = get_available_reg(reg, reg_status)
while rd == "x1":
rd = get_available_reg(reg, reg_status)
f.write(f"\tlhu {rd}, {imm}({rs1})\n")
reg_status[rd] = 4 # 解决数据冲突
update_reg_status(reg_status) # 更新寄存器状态
reg_status[rd] = 4
update_reg_status(reg_status)
def test_lw():
f.write("\taddiw x1, x0, 1025\n")
insert_nop()
f.write("\tslli x1, x1, 0x15\n") # x1=0x80200000
f.write("\tslli x1, x1, 0x15\n") # x1 = 0x80200000
insert_nop()
rd = get_available_reg(reg, reg_status)
while rd == "x1":
rd = get_available_reg(reg, reg_status)
rs1 = "x1"
# Align immediate for word access (multiple of 4)
imm = random.randint(-(2**11), 2**11 - 1) & 0xFFFFFFFFFFFFFFFC
f.write(f"\tsw {rd}, {imm}({rs1})\n")
f.write(f"\tlw {rd}, {imm}({rs1})\n")
reg_status[rd] = 4 # 解决数据冲突
update_reg_status(reg_status) # 更新寄存器状态
reg_status[rd] = 4
update_reg_status(reg_status)
rd = get_available_reg(reg, reg_status)
while rd == "x1":
rd = get_available_reg(reg, reg_status)
f.write(f"\tlwu {rd}, {imm}({rs1})\n")
reg_status[rd] = 4 # 解决数据冲突
update_reg_status(reg_status) # 更新寄存器状态
reg_status[rd] = 4
update_reg_status(reg_status)
def test_ld():
f.write("\taddiw x1, x0, 1025\n")
insert_nop()
f.write("\tslli x1, x1, 0x15\n") # x1=0x80200000
f.write("\tslli x1, x1, 0x15\n") # x1 = 0x80200000
insert_nop()
rd = get_available_reg(reg, reg_status)
while rd == "x1":
rd = get_available_reg(reg, reg_status)
rs1 = "x1"
# Align immediate for doubleword access (multiple of 8)
imm = random.randint(-(2**11), 2**11 - 1) & 0xFFFFFFFFFFFFFFF8
f.write(f"\tsd {rd}, {imm}({rs1})\n")
f.write(f"\tld {rd}, {imm}({rs1})\n")
reg_status[rd] = 4 # 解决数据冲突
update_reg_status(reg_status) # 更新寄存器状态
reg_status[rd] = 4
update_reg_status(reg_status)
def test_store_load_cycle():
"""
This function stores several registers into memory using store instructions
with properly aligned immediates, then overwrites those memory addresses,
and finally loads the values back using the corresponding load instructions.
"""
# Set up x1 as the memory base address (0x80200000)
f.write("\taddiw x1, x0, 1025\n")
insert_nop()
f.write("\tslli x1, x1, 0x15\n")
insert_nop()
cycle_count = 5 # Number of store instructions in each cycle.
store_entries = []
# First, store values using a randomly chosen store instruction.
for _ in range(cycle_count):
rd = get_available_reg(reg, reg_status)
while rd == "x1":
rd = get_available_reg(reg, reg_status)
store_inst = random.choice(inst_store)
if store_inst == "sb":
imm = random.randint(-(2**11), 2**11 - 1)
elif store_inst == "sh":
# Align immediate to an even address.
imm = random.randint(-(2**11), 2**11 - 1) & 0xFFFFFFFFFFFFFFFE
elif store_inst == "sw":
# Align immediate to a multiple of 4.
imm = random.randint(-(2**11), 2**11 - 1) & 0xFFFFFFFFFFFFFFFC
elif store_inst == "sd":
# Align immediate to a multiple of 8.
imm = random.randint(-(2**11), 2**11 - 1) & 0xFFFFFFFFFFFFFFF8
f.write(f"\t{store_inst} {rd}, {imm}(x1)\n")
store_entries.append((store_inst, imm, rd))
reg_status[rd] = 4
update_reg_status(reg_status)
# Overwrite the previously stored addresses with new values.
overwrite_entries = []
for _ in range(cycle_count):
rd = get_available_reg(reg, reg_status)
while rd == "x1":
rd = get_available_reg(reg, reg_status)
store_inst = random.choice(inst_store)
if store_inst == "sb":
imm = random.randint(-(2**11), 2**11 - 1)
elif store_inst == "sh":
imm = random.randint(-(2**11), 2**11 - 1) & 0xFFFFFFFFFFFFFFFE
elif store_inst == "sw":
imm = random.randint(-(2**11), 2**11 - 1) & 0xFFFFFFFFFFFFFFFC
elif store_inst == "sd":
imm = random.randint(-(2**11), 2**11 - 1) & 0xFFFFFFFFFFFFFFF8
f.write(f"\t{store_inst} {rd}, {imm}(x1)\n")
overwrite_entries.append((store_inst, imm, rd))
reg_status[rd] = 4
update_reg_status(reg_status)
# Now, load back the values stored in the first cycle.
for store_inst, imm, reg_written in store_entries:
rd = get_available_reg(reg, reg_status)
while rd == "x1":
rd = get_available_reg(reg, reg_status)
# Choose an appropriate load instruction corresponding to the store type.
if store_inst == "sb":
load_inst = random.choice(["lb", "lbu"])
elif store_inst == "sh":
load_inst = random.choice(["lh", "lhu"])
elif store_inst == "sw":
load_inst = random.choice(["lw", "lwu"])
elif store_inst == "sd":
load_inst = "ld"
f.write(f"\t{load_inst} {rd}, {imm}(x1)\n")
reg_status[rd] = 4
update_reg_status(reg_status)
# Similarly, load back the values from the overwrite cycle.
for store_inst, imm, reg_written in overwrite_entries:
rd = get_available_reg(reg, reg_status)
while rd == "x1":
rd = get_available_reg(reg, reg_status)
if store_inst == "sb":
load_inst = random.choice(["lb", "lbu"])
elif store_inst == "sh":
load_inst = random.choice(["lh", "lhu"])
elif store_inst == "sw":
load_inst = random.choice(["lw", "lwu"])
elif store_inst == "sd":
load_inst = "ld"
f.write(f"\t{load_inst} {rd}, {imm}(x1)\n")
reg_status[rd] = 4
update_reg_status(reg_status)
# Create the build directory if it doesn't exist.
if not os.path.exists("build"):
os.mkdir("build")
with open("./build/{}.s".format(file_name), "w") as f:
f.write(".text\n")
f.write(".global _start\n")
f.write("_start:\n")
# Generate some immediate and LUI instructions.
for i in range(100):
test_imm_inst()
test_lui_inst()
@ -223,7 +322,7 @@ with open("./build/{}.s".format(file_name), "w") as f:
test_reg_inst()
random.choice([test_imm_inst, test_lui_inst, test_reg_inst])()
random.choice(instructions)()
# 结束程序
# End the program.
wait_gpr(3)
f.write("\tli x3, 1\n")
wait_gpr(17)

Loading…
Cancel
Save