diff --git a/CMakeLists.txt b/CMakeLists.txt index 475dbc7..49e6bdd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,10 @@ set(CMAKE_CXX_STANDARD 20) include_directories(include) -add_executable(simulator ${sources}) +# add_executable(simulator ${sources}) add_executable(alu demo/alu.cpp) + +# For debug build +add_executable(modules demo/modules.cpp) +target_compile_definitions(modules PRIVATE _DEBUG) diff --git a/demo/modules.cpp b/demo/modules.cpp new file mode 100644 index 0000000..d07b085 --- /dev/null +++ b/demo/modules.cpp @@ -0,0 +1,101 @@ +#include "tools.h" +#include + +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 , 32> regs; +}; + +struct RegFile : dark::Module { + 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 { + 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; +} diff --git a/include/bit_impl.h b/include/bit_impl.h index 609bdec..39b89e2 100644 --- a/include/bit_impl.h +++ b/include/bit_impl.h @@ -13,7 +13,7 @@ constexpr auto int_concat(max_size_t arg, auto... args) { template 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 { max_ssize_t _M_data : _Old; } tmp; diff --git a/include/operator.h b/include/operator.h index 23bb701..d110606 100644 --- a/include/operator.h +++ b/include/operator.h @@ -1,5 +1,6 @@ #pragma once #include "bit.h" +#include "register.h" namespace dark { @@ -75,7 +76,7 @@ constexpr auto operator^(const _Tp &lhs, const _Up &rhs) { } template -concept int_or_bit = int_type<_Tp> || bit_type<_Tp>; +concept int_or_bit = int_type<_Tp> || bit_type>; template 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)); } -template -constexpr bool operator&&(const _Tp &lhs, const _Up &rhs) { - return cast(lhs) && cast(rhs); -} - -template -constexpr bool operator||(const _Tp &lhs, const _Up &rhs) { - return cast(lhs) || cast(rhs); -} - template constexpr bool operator==(const _Tp &lhs, const _Up &rhs) { return cast(lhs) == cast(rhs); } +template +inline constexpr bool is_reg_ref_v = false; + +template +inline constexpr bool is_reg_ref_v &> = true; + template -constexpr auto operator<=>(const _Tp &lhs, const _Up &rhs) { +constexpr auto operator <=> (const _Tp &lhs, const _Up &rhs) { return cast(lhs) <=> cast(rhs); } - } // namespace dark diff --git a/include/tools.h b/include/tools.h index 7f273a2..7e190cb 100644 --- a/include/tools.h +++ b/include/tools.h @@ -24,10 +24,10 @@ using dark::max_ssize_t; template constexpr auto to_unsigned(const _Tp &x) { - return static_cast(x); + return static_cast(x); } template constexpr auto to_signed(const _Tp &x) { - return static_cast(sign_extend(x)); + return static_cast(static_cast(sign_extend(x))); }