Merge branch 'DarkSharpness:main' into main
This commit is contained in:
@ -7,6 +7,10 @@ set(CMAKE_CXX_STANDARD 20)
|
|||||||
|
|
||||||
include_directories(include)
|
include_directories(include)
|
||||||
|
|
||||||
add_executable(simulator ${sources})
|
# add_executable(simulator ${sources})
|
||||||
|
|
||||||
add_executable(alu demo/alu.cpp)
|
add_executable(alu demo/alu.cpp)
|
||||||
|
|
||||||
|
# For debug build
|
||||||
|
add_executable(modules demo/modules.cpp)
|
||||||
|
target_compile_definitions(modules PRIVATE _DEBUG)
|
||||||
|
101
demo/modules.cpp
Normal file
101
demo/modules.cpp
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#include "tools.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
struct RegFile_Input {
|
||||||
|
Wire <5> rs1_index; // Read
|
||||||
|
Wire <5> rs2_index; // Read
|
||||||
|
|
||||||
|
Wire <5> wb_index; // Writeback
|
||||||
|
Wire <1> wb_enable; // Writeback enabled?
|
||||||
|
Wire <32> wb_data; // Data to writeback
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RegFile_Output {
|
||||||
|
Register <32> rs1_data; // Read
|
||||||
|
Register <32> rs2_data; // Read
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RegFile_Private {
|
||||||
|
std::array <Register<32>, 32> regs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RegFile : dark::Module <RegFile_Input, RegFile_Output, RegFile_Private> {
|
||||||
|
void work() override final {
|
||||||
|
rs1_data <= regs[to_unsigned(rs1_index)];
|
||||||
|
rs2_data <= regs[to_unsigned(rs2_index)];
|
||||||
|
|
||||||
|
if (wb_enable && wb_index != 0) {
|
||||||
|
regs[to_unsigned(wb_index)] <= wb_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct InsDecode_Input {
|
||||||
|
Wire <32> rs1_data;
|
||||||
|
Wire <32> rs2_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct InsDecode_Output {
|
||||||
|
Register <5> rs1_index;
|
||||||
|
Register <5> rs2_index;
|
||||||
|
Register <5> wb_index;
|
||||||
|
Register <32> wb_data;
|
||||||
|
Register <1> wb_enable;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct InsDecode : dark::Module <InsDecode_Input, InsDecode_Output> {
|
||||||
|
void work() override final {
|
||||||
|
char c;
|
||||||
|
max_size_t x;
|
||||||
|
max_size_t y;
|
||||||
|
std::cin >> c >> x >> y;
|
||||||
|
if (c == 'r') {
|
||||||
|
rs1_index <= x;
|
||||||
|
rs2_index <= y;
|
||||||
|
wb_index <= 0;
|
||||||
|
wb_data <= 0;
|
||||||
|
wb_enable <= 0;
|
||||||
|
} else {
|
||||||
|
rs1_index <= 0;
|
||||||
|
rs2_index <= 0;
|
||||||
|
wb_index <= x;
|
||||||
|
wb_data <= y;
|
||||||
|
wb_enable <= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "rs1_data: " << to_unsigned(rs1_data) << std::endl;
|
||||||
|
std::cout << "rs2_data: " << to_unsigned(rs2_data) << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
signed main() {
|
||||||
|
InsDecode ins_decode;
|
||||||
|
RegFile reg_file;
|
||||||
|
|
||||||
|
dark::CPU cpu;
|
||||||
|
|
||||||
|
cpu.add_module(&ins_decode);
|
||||||
|
cpu.add_module(®_file);
|
||||||
|
|
||||||
|
reg_file.rs1_index = [&]() -> auto & { return ins_decode.rs1_index; };
|
||||||
|
reg_file.rs2_index = [&]() -> auto & { return ins_decode.rs2_index; };
|
||||||
|
reg_file.wb_index = [&]() -> auto & { return ins_decode.wb_index; };
|
||||||
|
reg_file.wb_enable = [&]() -> auto & { return ins_decode.wb_enable; };
|
||||||
|
reg_file.wb_data = [&]() -> auto & { return ins_decode.wb_data; };
|
||||||
|
|
||||||
|
ins_decode.rs1_data = [&]() -> auto & { return reg_file.rs1_data; };
|
||||||
|
ins_decode.rs2_data = [&]() -> auto & { return reg_file.rs2_data; };
|
||||||
|
|
||||||
|
cpu.run(114514, true);
|
||||||
|
|
||||||
|
// Demo input:
|
||||||
|
// w 1 2 (output 0 0)
|
||||||
|
// r 1 2 (output 0 0)
|
||||||
|
// w 2 3 (output 0 0)
|
||||||
|
// r 1 2 (output 2 0)
|
||||||
|
// r 1 2 (output 0 0)
|
||||||
|
// r 1 2 (output 2 3)
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -13,7 +13,7 @@ constexpr auto int_concat(max_size_t arg, auto... args) {
|
|||||||
|
|
||||||
template<std::size_t _Old, std::size_t _New = kMaxLength>
|
template<std::size_t _Old, std::size_t _New = kMaxLength>
|
||||||
constexpr auto sign_extend(max_size_t val) {
|
constexpr auto sign_extend(max_size_t val) {
|
||||||
static_assert(_Old < _New, "sign_extend: _Old should be less than _New");
|
static_assert(_Old <= _New, "sign_extend: _Old should be less than _New");
|
||||||
struct {
|
struct {
|
||||||
max_ssize_t _M_data : _Old;
|
max_ssize_t _M_data : _Old;
|
||||||
} tmp;
|
} tmp;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "bit.h"
|
#include "bit.h"
|
||||||
|
#include "register.h"
|
||||||
|
|
||||||
namespace dark {
|
namespace dark {
|
||||||
|
|
||||||
@ -75,7 +76,7 @@ constexpr auto operator^(const _Tp &lhs, const _Up &rhs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
concept int_or_bit = int_type<_Tp> || bit_type<_Tp>;
|
concept int_or_bit = int_type<_Tp> || bit_type<std::decay_t<_Tp>>;
|
||||||
|
|
||||||
template<bit_type _Tp, int_or_bit _Up>
|
template<bit_type _Tp, int_or_bit _Up>
|
||||||
constexpr auto operator<<(const _Tp &lhs, const _Up &rhs) {
|
constexpr auto operator<<(const _Tp &lhs, const _Up &rhs) {
|
||||||
@ -107,25 +108,20 @@ constexpr auto operator-(const _Tp &value) {
|
|||||||
return Bit<_Tp::_Bit_Len>(-cast(value));
|
return Bit<_Tp::_Bit_Len>(-cast(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<int_or_bit _Tp, int_or_bit _Up>
|
|
||||||
constexpr bool operator&&(const _Tp &lhs, const _Up &rhs) {
|
|
||||||
return cast(lhs) && cast(rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int_or_bit _Tp, int_or_bit _Up>
|
|
||||||
constexpr bool operator||(const _Tp &lhs, const _Up &rhs) {
|
|
||||||
return cast(lhs) || cast(rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int_or_bit _Tp, int_or_bit _Up>
|
template<int_or_bit _Tp, int_or_bit _Up>
|
||||||
constexpr bool operator==(const _Tp &lhs, const _Up &rhs) {
|
constexpr bool operator==(const _Tp &lhs, const _Up &rhs) {
|
||||||
return cast(lhs) == cast(rhs);
|
return cast(lhs) == cast(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename _Tp>
|
||||||
|
inline constexpr bool is_reg_ref_v = false;
|
||||||
|
|
||||||
|
template <std::size_t _Len>
|
||||||
|
inline constexpr bool is_reg_ref_v<Register<_Len> &> = true;
|
||||||
|
|
||||||
template<int_or_bit _Tp, int_or_bit _Up>
|
template<int_or_bit _Tp, int_or_bit _Up>
|
||||||
constexpr auto operator<=>(const _Tp &lhs, const _Up &rhs) {
|
constexpr auto operator <=> (const _Tp &lhs, const _Up &rhs) {
|
||||||
return cast(lhs) <=> cast(rhs);
|
return cast(lhs) <=> cast(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace dark
|
} // namespace dark
|
||||||
|
@ -24,10 +24,10 @@ using dark::max_ssize_t;
|
|||||||
|
|
||||||
template<dark::concepts::bit_type _Tp>
|
template<dark::concepts::bit_type _Tp>
|
||||||
constexpr auto to_unsigned(const _Tp &x) {
|
constexpr auto to_unsigned(const _Tp &x) {
|
||||||
return static_cast<dark::max_size_t>(x);
|
return static_cast<max_size_t>(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<dark::concepts::bit_type _Tp>
|
template<dark::concepts::bit_type _Tp>
|
||||||
constexpr auto to_signed(const _Tp &x) {
|
constexpr auto to_signed(const _Tp &x) {
|
||||||
return static_cast<dark::max_ssize_t>(sign_extend(x));
|
return static_cast<max_ssize_t>(static_cast<max_size_t>(sign_extend(x)));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user