Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- MCS4::Chip4004::Chip4004(Circuit circuit_):
- circuit(circuit_)
- {
- circuit._list_out_map.resize(circuit._nodes.size());
- circuit._group_map.resize(circuit._nodes.size());
- circuit.stabilizeChip();
- runInitSequence();
- }
- void MCS4::Chip4004::coldReset()
- {
- ComponentIndex index = 0;
- for(auto& node: circuit._nodes) {
- node.value = false;
- circuit._list_out.push_back(index);
- ++index;
- }
- for(auto& t: circuit._transistors) {
- t.on = false;
- }
- circuit.stabilizeChip();
- }
- void MCS4::Chip4004::runInitSequence()
- {
- for(cycle=0; cycle<1100; ++cycle)
- {
- od::bitfield<16> bitset;
- bitset[unsigned(Input::Clk1)] = (cycle+3) % 4 == 0;
- bitset[unsigned(Input::Clk2)] = (cycle+1) % 4 == 0;
- bitset[unsigned(Input::Sync)] = (cycle > 4)?(((cycle+32)/4)%8 == 0): 0;
- bitset[unsigned(Input::Test)] = true;
- bitset[unsigned(Input::Poc)] = (cycle < 1099);
- for(unsigned i=0; i<circuit._inputs.size(); ++i) {
- bool value = bitset[i];
- circuit._nodes[circuit._inputs[i]].pullup = value;
- circuit._nodes[circuit._inputs[i]].pulldown = !value;
- circuit._list_out.push_back(circuit._inputs[i]);
- }
- circuit.recalcNodeList();
- }
- }
- bool MCS4::Chip4004::read(Input input) const
- {
- return circuit._nodes.at(circuit._inputs.at(unsigned(input))).value;
- }
- bool MCS4::Chip4004::read(Output output) const
- {
- return circuit._nodes.at(circuit._outputs.at(unsigned(output))).value;
- }
- MCS4::MCS4(Circuit circuit_):
- chip_4004(circuit_)
- {
- // init rom data
- std::vector<uint8_t> temp = {
- 0x20, 0xFF, 0x22, 0xFF, 0x24, 0xFF,
- 0x26, 0xFF, 0x28, 0xFF, 0x2A, 0xFF,
- 0x2C, 0xFF, 0x2E, 0xFF};
- setProgram(temp);
- }
- void MCS4::setProgram(std::vector<uint8_t> program)
- {
- roms.data.clear();
- for(uint8_t b: program) {
- roms.data.push_back((b>>4)&0xF);
- roms.data.push_back(b&0xF);
- }
- }
- void MCS4::simulateOneClockPhase()
- {
- auto& circuit = chip_4004.circuit;
- std::bitset<16> bitset, update;
- cmrom = chip_4004.read(Chip4004::Output::CM_Rom);
- d0_pad = chip_4004.read(Chip4004::Input::D0);
- d1_pad = chip_4004.read(Chip4004::Input::D1);
- d2_pad = chip_4004.read(Chip4004::Input::D2);
- d3_pad = chip_4004.read(Chip4004::Input::D3);
- updateSignals();
- bitset = signals();
- update = signalsToUpdate();
- for(unsigned i=0; i<circuit._inputs.size(); ++i) {
- if(!update[i])
- {
- circuit._nodes[circuit._inputs[i]].pullup = false;
- circuit._nodes[circuit._inputs[i]].pulldown = false;
- circuit._list_out.push_back(circuit._inputs[i]);
- continue;
- }
- bool value = bitset[i];
- circuit._nodes[circuit._inputs[i]].pullup = value;
- circuit._nodes[circuit._inputs[i]].pulldown = !value;
- circuit._list_out.push_back(circuit._inputs[i]);
- }
- circuit.recalcNodeList();
- }
- void MCS4::simulateOneInstructionCycle()
- {
- for(unsigned i=0; i<32; ++i) {
- simulateOneClockPhase();
- }
- }
- void MCS4::updateSignals() {
- auto& cycle = chip_4004.cycle;
- const bool pp_sync = (cycle > 4)?(((cycle+30)/4)%8 == 0): 0;
- const bool p_sync = (cycle > 4)?(((cycle+31)/4)%8 == 0): 0;
- clk1 = (cycle+3) % 4 == 0;
- clk2 = (cycle+1) % 4 == 0;
- sync = (cycle > 4)?(((cycle+32)/4)%8 == 0): 0;
- test_pad = false;
- poc_pad = false;
- if(cmrom_prev && !cmrom) {
- d0_pad = d1_pad = d2_pad = d3_pad = true;
- read_rom = true;
- read_cycle = 0;
- }
- if(read_rom)
- {
- const unsigned rom_index = rom_cursor*2 + (read_cycle >= 4);
- const uint8_t data = rom_index < roms.data.size()?
- roms.data[rom_index]: 0;
- d0_pad = (data >> 0) & 0x1;
- d1_pad = (data >> 1) & 0x1;
- d2_pad = (data >> 2) & 0x1;
- d3_pad = (data >> 3) & 0x1;
- if(read_cycle == 10) {
- read_rom = false;
- }
- else {
- ++read_cycle;
- }
- }
- if(pp_sync && !p_sync) {
- read_addr = true;
- read_addr_cycle = 0;
- rom_cursor = 0;
- }
- if(read_addr) {
- if(read_addr_cycle % 4 == 0) {
- uint8_t w = 0;
- w |= d0_pad << 0;
- w |= d1_pad << 1;
- w |= d2_pad << 2;
- w |= d3_pad << 3;
- rom_cursor = rom_cursor<<4 | w;
- //std::cout << "w: " << int(w) << std::endl;
- if(read_addr_cycle >= 8) {
- read_addr = false;
- rom_cursor =
- ((rom_cursor&0xF00)>>8) |
- (rom_cursor&0x0F0) |
- ((rom_cursor&0x00F)<<8);
- }
- }
- ++read_addr_cycle;
- }
- ++cycle;
- cmrom_prev = cmrom;
- }
- std::bitset<16> MCS4::signals() const {
- std::bitset<16> bitset;
- bitset[0] = clk1;
- bitset[1] = clk2;
- bitset[2] = sync;
- if(read_rom) {
- bitset[3] = d0_pad;
- bitset[4] = d1_pad;
- bitset[5] = d2_pad;
- bitset[6] = d3_pad;
- }
- bitset[7] = test_pad;
- bitset[8] = poc_pad;
- return bitset;
- }
- std::bitset<16> MCS4::signalsToUpdate() const {
- std::bitset<16> bitset;
- bitset[0] = true;
- bitset[1] = true;
- bitset[2] = true;
- if(read_rom) {
- bitset[3] = true;
- bitset[4] = true;
- bitset[5] = true;
- bitset[6] = true;
- }
- bitset[7] = true;
- bitset[8] = true;
- return bitset;
- }
Advertisement
Add Comment
Please, Sign In to add comment