Lubomir Bogdanov Posted February 2 Report Share Posted February 2 Hello everyone, I was wondering if it is possible to connect two signals from different SC_MODULEs together without ports? The reason I want to try this is my flash_memory model - I want it to receive an address on a rising edge of its clock signal and produce the resulting word on the falling edge of that same clock. However, if I use ports, I get additional delays because the ports are buffered (I guess). Here is a highly generalized model of my system with ports: SC_MODULE(micrcontroller){ sc_in_clk clock {"mcu_clock"}; sc_signal<bool, SC_MANY_WRITERS> read_write {"mcu_read_write"}; sc_signal<bool, SC_MANY_WRITERS> interrupt_request {"mcu_interrupt_request"}; sc_signal<sc_lv<16>, SC_MANY_WRITERS> instr_data_bus {"mcu_instr_data_bus"}; sc_signal<sc_lv<20>, SC_MANY_WRITERS> address_bus {"mcu_address_bus"}; microprocessor *cpu; flash_memory *flash; sram_memory *sram; micrcontroller(::sc_core::sc_module_name); ~micrcontroller(); }; SC_MODULE(microprocessor){ sc_in_clk clock {"upu_clock"}; sc_out<bool> read_write {"upu_read_write"}; sc_in<bool> interrupt_request {"upu_interrupt_request"}; sc_inout<sc_lv<16>> instr_data_bus {"upu_instr_data_bus"}; sc_out<sc_lv<20>> address_bus {"upu_address_bus"}; void fetch(); void decode(); void execute(); void interrupt(); SC_CTOR(microprocessor){ SC_CTHREAD(fetch, clock.value_changed()); SC_CTHREAD(decode, clock.value_changed()); SC_CTHREAD(execute, clock.value_changed()); SC_CTHREAD(interrupt, clock.value_changed()); } ~microprocessor(); }; SC_MODULE(flash_memory){ sc_in_clk clock {"flash_memory_clock"} ; sc_in<bool> read_write {"flash_memory_read_write"}; sc_inout<sc_lv<16>> data_bus {"flash_memory_data_bus"}; sc_in<sc_lv<20>> address_bus {"flash_memory_address_bus"}; void flash_loop(); SC_CTOR(flash_memory){ SC_CTHREAD(flash_loop, clock.value_changed()); } ~flash_memory(); }; SC_MODULE(sram_memory){ sc_in_clk clock {"sram_memory_clock"} ; sc_in<bool> read_write {"sram_memory_read_write"}; sc_inout<sc_lv<16>> data_bus {"sram_memory_data_bus"}; sc_in<sc_lv<20>> address_bus {"sram_memory_address_bus"}; void sram_loop(); SC_CTOR(sram_memory){ SC_CTHREAD(sram_loop, clock.value_changed()); } ~sram_memory(); }; and in the microcontroller's (top-level module) constructor I connect them with signals like this: microcontroller::microcontroller(::sc_core::sc_module_name){ read_write = 1; interrupt_request = 0; instr_data_bus = 0x00; address_bus = 0x00; cpu = new microprocessor("cpu"); cpu->address_bus(address_bus); cpu->instr_data_bus(instr_data_bus); cpu->clock(clock); cpu->read_write(read_write); cpu->interrupt_request(interrupt_request); flash = new flash_memory("flash"); flash->address_bus(address_bus); flash->data_bus(instr_data_bus); flash->clock(clock); flash->read_write(read_write); sram = new sram_memory("sram"); sram->address_bus(address_bus); sram->data_bus(instr_data_bus); sram->clock(clock); sram->read_write(read_write); } This yields: ============== 1 ============== (microprocessor) r0: 004402 address_bus: 004400 instr_data_bus: 00000 r: mem[004400] = 0 ============== 0 ============== (microprocessor) r0: 004402 address_bus: 004400 instr_data_bus: 00000 r: mem[004400] = 0 ============== 1 ============== (microprocessor) r0: 004404 address_bus: 004402 instr_data_bus: 0e0f2 r: mem[004402] = e0f2 which is half-a-period longer than I what I want. I've noticed that I can do this: SC_MODULE(micrcontroller){ sc_in_clk clock {"mcu_clock"}; sc_signal<bool, SC_MANY_WRITERS> read_write {"mcu_read_write"}; sc_signal<bool, SC_MANY_WRITERS> interrupt_request {"mcu_interrupt_request"}; sc_signal<sc_lv<16>, SC_MANY_WRITERS> instr_data_bus {"mcu_instr_data_bus"}; sc_signal<sc_lv<20>, SC_MANY_WRITERS> address_bus {"mcu_address_bus"}; void cpu(); void flash(); void sram(); SC_CTOR(micrcontroller){ SC_CTHREAD(cpu, clock.value_changed()); SC_CTHREAD(flash, clock.value_changed()); SC_CTHREAD(sram, clock.value_changed()); } ~micrcontroller(); }; then I would only use signals without ports and there is no delay in the communication. However, this would break my module separation and I fear that at some point, as the system gets more and more complex, I might get into some nasty spaghetti code. Regards, L. B. Quote Link to comment Share on other sites More sharing options...
David Black Posted February 2 Report Share Posted February 2 Ports are not buffered. Ports are effectively pointers to channels. You cannot connect ports to ports unless they are hierarchical wrt to each other. You can connect ports to sc_exports. None of this will make much sense until you understand the fundamental nature and purpose of channels, interfaces and ports. SystemC is C++. Forget any ideas you have from Verilog or VHDL (although there are parallel ideas). When you write to a port, you are effectively writing to a channel pointed to or referenced by the port. And when you write to a channel, you are calling a subroutine located inside that channel class. sc_signal is a very primitive channel. A channel is a class implementing an interface (abstract class). The port is bound to the interface and accesses the methods through polymorphism. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.