contributed by <liballouo
>
C
in Quiz 1We test our code using Ripes simulator.
You can see the entire code here.
Info | Value |
---|---|
Cycle | 443 |
Instrs. retired | 322 |
CPI | 1.38 |
IPC | 0.727 |
Clock rate | 0 Hz |
Counting leading zero utilizes population count.
You can see the entire code here.
Info | Value |
---|---|
Cycle | 194 |
Instrs. retired | 151 |
CPI | 1.28 |
IPC | 0.778 |
Clock rate | 0 Hz |
Input: 0x3
Output: 30
Input: 0xFFFFFFFF
Output: 0
Input: 0x3321675
Output: 6
Q1. Construct the Minimum Bitwise Array II
You are given an array nums
consisting of n
prime integers.
You need to construct an array ans
of length n
, such that, for each index i
, the bitwise OR
of ans[i]
and ans[i] + 1
is equal to nums[i]
, i.e. ans[i] OR (ans[i] + 1) == nums[i]
.
Additionally, you must minimize each value of ans[i]
in the resulting array.
If it is not possible to find such a value for ans[i]
that satisfies the condition, then set ans[i] = -1
.
A prime number is a natural number greater than 1 with only two factors, 1 and itself.
1 <= nums.length <= 100
2 <= nums[i] <= 10^9
nums[i]
is a prime number.There are three cases to consider:
nums[i] = 2
, then ans[i] = -1
.nums[i]
consists of all 1s in binary representation, then ans[i] = nums[i] >> 1
.Here's an example for Case 3:
We implement it in C.
You can see the entire code here.
To handle different cases, the solution involves multiple functions:
minBitwiseNum
FunctionThis function determines the appropriate value for ans
based on the input num
.
num
equals 2, for which there is no valid solution for ans
, so the function returns -1.num
has all 1s in its binary representation (e.g., 3, 7, 15). The condition uses the ilog2
function to get the number of bits required and popcount
to check if all bits are set.helper
function finds the correct value.ilog2
FunctionThis function calculates the integer logarithm base 2 of a number using the my_clz
function to count leading zeros.
my_clz
FunctionThe my_clz
function counts the number of leading zeros in a 32-bit unsigned integer. It uses bitwise operations to set all bits to 1 to the right of the highest set bit and then uses popcount
to calculate the number of 1s. Last, it returns the value of leading zero.
popcount
FunctionThe popcount
function counts the number of 1s in the binary representation of a number. It uses bit manipulation techniques to sum the bits in groups, eventually reducing to a count of all 1s.
helper
FunctionThe helper
function is used to find the minimum possible value for ans
when the number does not fit into the special cases. It looks for the rightmost 0 bit and clears the bit immediately to its left.
After finishing the C code, we translate it from C code to a RISC-V assembly program.
You can see the entire code here.
Input: 2
Output: -1
Input: 3
Output: 1
Input: 5
Output: 4
Input: 7
Output: 3
Input: 31
Output: 15
Input: 307
Output: 305
Input: 383
Output: 319
Input: 5039
Output: 5031
Info | Value |
---|---|
Cycle | 6522 |
Instrs. retired | 5066 |
CPI | 1.26 |
IPC | 0.777 |
Clock rate | 0 Hz |
Info | Value |
---|---|
Cycle | 1056 |
Instrs. retired | 806 |
CPI | 1.31 |
IPC | 0.763 |
Clock rate | 0 Hz |
The pseudo instruction below is popcount
part of the code run on Ripes.
We choose 5-stage pipelined processor as the processor we use in Ripes to run the code. Its block diagram look like this:
The "5-stage" means this processor using five-stage pipeline to parallelize instructions. The stages are:
IF
: Instruction fetchID
: Instruction decode and register fetchEX
: ExecuteMEM
: Memory accessWB
: Register write backTo illustrate, we take the instruction lui t1, 0x55555
as an example. According to The RISC-V Instruction Set Manual
LUI
(load upper immediate) is used to build 32-bit constants and uses the U-type format.LUI
places the U-immediate value in the top 20 bits of the destination registerrd
, filling in the lowest 12 bits with zeros.
The layout of the U-format instructions is:
imm [31:12] | rd [11:7] | opcode [6:0] |
---|
The pseudo instruction is lui x6 0x55555
which decoded into 55555337
.
imm [31:12] | rd [11:7] | opcode [6:0] | representation |
---|---|---|---|
01010101010101010101 | 00110 | 0110111 | binary |
0x55555 | 0x6 | 0x37 | heximal |
IF
: Instruction fetchPC
starts at 0x000000cc
. PC+4
will pass to the following stages for further usages.0x000000cc
from instruction memory, resulting in the instruction 0x55555337
.ID
: Instruction decode and register fetch0x55555337
is decoded, revealing lui x6, 0x55555
.
opcode = LUI
Imm. = 0x55555000
Wr idx = 0x06
rs1 = 0x0a
and rs2 = 0x15
. These fields are irrelevant for this instruction.
rs1
and rs2
are fetched, resulting in Reg 1 = 0x00000003
and Reg 2 = 0x00000000
, but they are not used in this instruction.PC
and PC+4
are passed unchanged to the next stage.EX
: ExecutePC+4
, so we just let it pass.Reg 1
and Reg 2
in U-type format instructions, so after their value passes the multiplexers, they are filtered. The result of ALU is just 0x55555000
from Imm.
.rd
is not used in this stage, so it just passes to the next stage.MEM
: Memory accessPC+4
is still passed to the next stage.0x00000000
, indicating that no memory access occurred.WB
: Register write backrd = 0x06
and imm = 0x55555000
to Wr idx
and Wr data
respectively.
After completing these five stages, the register x6(t1)
is set to 0x55555000
.
The RISC-V Instruction Set Manual
Quiz1 of Computer Architecture (2023 Fall)
Quiz1 of Computer Architecture (2024 Fall)