- Ở bài trước mình đã giới thiệu một kênh Primitive trong SystemC đó là: sc_mutex. Phần này mình sẽ giới thiệu hai kênh còn lại là sc_semaphore và sc_fifo.
1. sc_semaphore.
- sc_semaphore là một kênh Primitive được định nghĩa trước mục đích để mô hình hành vi của một semaphore phần mềm được sử dụng cung cấp hạn chế truy cập cùng lúc đến một tài nguyên được chia sẻ. Đối với một số tài nguyên, bạn có thể có nhiều hơn một bản sao hoặc người sở hữu. Một ví dụ dễ hiểu hơn về điều này là chỗ đậu xe trong một bãi đậu xe. Để quản lý các loại tài nguyên, SystemC cung cấp sc_semaphore. Semaphore có giá trị là số nguyên, giá trị semaphore được thiết lập với số lượng cho phép truy cập đồng thời khi semaphore được xây dựng.
- Truy cập sc_semaphore gồm đợi cho một nguồn tài nguyên có sẵn và sau đó gửi thông báo khi hoàn thành với nguồn tài nguyên đó.
*** Ví dụ một số loại sc_semaphore và cú pháp:
- Chúng ta thấy rằng sc_semaphore:: wait() là method khác nhau rõ rệt với wait() đã giưới thiệu ở bài trước. Trên thực tế sc_semaphore:: wait() được thực hiện với wait(event).
- Một model bộ nhớ đa cổng là một ví dụ tốt về một ứng dụng thiết kế system-level với sc_semaphore. Chúng ta có thể sử dụng semaphore để chỉ số lượng truy cập của read or write được cho phép.
2. sc_fifo
- sc_fifo là một kênh Primitive được định nghĩa trước nhằm mô hình hành vi của một FIFO, đó là một bộ đệm first-in first-out. FIFO là một đối tượng của lớp sc_fifo và có chức nang là quản lý nguồn dữ liệu. Mỗi FIFO có một số khe để lưu trữ giá trị. Số lượng các khe được xác định khi đối tượng được xây dựng, kích thước khe mặc định là 16. Kiểu dữ liệu của các phần tử này cũng cần phải được định rõ. Một sc_fifo có thể chứa bất kỳ loại dữ liệu, bao gồm các cấu trúc lớn và phức tạp (ví dụ: / IP TCP hoặc một disk block).
** Ví dụ và cú pháp:
** Một số loại methods sc_fifo:
write(): methods này write các giá trị thông qua một đối số vào FIFO. Nếu FIFO đầy thì hàm write() đợi cho đến khe FIFO có sẵn
nb_write(): methods này tương tự như write(), chỉ khác biệt là khi FIFO đầy nb_write() không đợi đến khi khe FIFO là có sẵn. Thay vào đó nó trả về false.
read(): methods này trả về tối thiểu các dữ liệu được write gần đây trong FIFO. Nếu FIFO rỗng, thì hàm read() đợi cho đến khi dữ liệu có sẵn trong FIFO.
nb_read(): methods này tương tự như read(), chỉ khác biệt là khi FIFO rỗng, nb_read() không đợi cho đến khi FIFO có dữ liệu. Thay vào đó nó trả về false.
num_available(): methods này trả về số lượng giá trị dữ liệu có sẵn trong fifo tại thời gian hiện tại.
num_free(): methods này trả về số lượng các khe rỗng có sẵn trong fifo tại thời gian hiện tại.
** Ứng dụng của FIFOs có thể được sử dụng để đệm dữ liệu giữa một bộ xử lý hình ảnh và bus, hoặc một hệ thống truyền thông có thể sử dụng FIFOs để đệm các gói thông tin khi đi ngang qua một mạng.
*** Ví dụ trong một chương trình SystemC.
*** Kết quả đầu ra:
1. sc_semaphore.
- sc_semaphore là một kênh Primitive được định nghĩa trước mục đích để mô hình hành vi của một semaphore phần mềm được sử dụng cung cấp hạn chế truy cập cùng lúc đến một tài nguyên được chia sẻ. Đối với một số tài nguyên, bạn có thể có nhiều hơn một bản sao hoặc người sở hữu. Một ví dụ dễ hiểu hơn về điều này là chỗ đậu xe trong một bãi đậu xe. Để quản lý các loại tài nguyên, SystemC cung cấp sc_semaphore. Semaphore có giá trị là số nguyên, giá trị semaphore được thiết lập với số lượng cho phép truy cập đồng thời khi semaphore được xây dựng.
- Truy cập sc_semaphore gồm đợi cho một nguồn tài nguyên có sẵn và sau đó gửi thông báo khi hoàn thành với nguồn tài nguyên đó.
*** Ví dụ một số loại sc_semaphore và cú pháp:
Mã:
sc_semaphore NAME(COUNT) ;
//To lock a mutex, NAME (wait until
// unlocked if in use)
NAME. wait();
// Non-blocking, returns true if success else false
NAME. trywait()
//Returns number of available semaphores
NAME. get_value()
//To free a previously locked mutex
NAME. post();
// tan gia tri semaphore khi process bị ngưng và dang doi gia trị semaphore tang len
- Một model bộ nhớ đa cổng là một ví dụ tốt về một ứng dụng thiết kế system-level với sc_semaphore. Chúng ta có thể sử dụng semaphore để chỉ số lượng truy cập của read or write được cho phép.
Mã:
class multiport_RAM {
sc_semaphore read_ports(3);
sc_semaphore write_ports(2);
void read(int addr, int& data) {
read_ports. wait();
// perform read
read_ports. post();
}
void write(int addr, int data) (
write_ports. lock();
// perform write
write_ports. unlock();
}
}; //endclass
- sc_fifo là một kênh Primitive được định nghĩa trước nhằm mô hình hành vi của một FIFO, đó là một bộ đệm first-in first-out. FIFO là một đối tượng của lớp sc_fifo và có chức nang là quản lý nguồn dữ liệu. Mỗi FIFO có một số khe để lưu trữ giá trị. Số lượng các khe được xác định khi đối tượng được xây dựng, kích thước khe mặc định là 16. Kiểu dữ liệu của các phần tử này cũng cần phải được định rõ. Một sc_fifo có thể chứa bất kỳ loại dữ liệu, bao gồm các cấu trúc lớn và phức tạp (ví dụ: / IP TCP hoặc một disk block).
** Ví dụ và cú pháp:
Mã:
sc_fifo<ELEMENT_TYPENAME> NAME(SIZE);
NAME. write ( VALUE);
NAME. read (REFERENCE);
= NAME. read () /* function style */
if (NAME. nb_read (REFERENCE)) { // Non-blocking
// true if success
}
if (NAME. num_available() == 0)
wait(NAME. data_written_event());
if (NAME. num_free() == 0)
next_trigger(NAME. data_read_event());
write(): methods này write các giá trị thông qua một đối số vào FIFO. Nếu FIFO đầy thì hàm write() đợi cho đến khe FIFO có sẵn
nb_write(): methods này tương tự như write(), chỉ khác biệt là khi FIFO đầy nb_write() không đợi đến khi khe FIFO là có sẵn. Thay vào đó nó trả về false.
read(): methods này trả về tối thiểu các dữ liệu được write gần đây trong FIFO. Nếu FIFO rỗng, thì hàm read() đợi cho đến khi dữ liệu có sẵn trong FIFO.
nb_read(): methods này tương tự như read(), chỉ khác biệt là khi FIFO rỗng, nb_read() không đợi cho đến khi FIFO có dữ liệu. Thay vào đó nó trả về false.
num_available(): methods này trả về số lượng giá trị dữ liệu có sẵn trong fifo tại thời gian hiện tại.
num_free(): methods này trả về số lượng các khe rỗng có sẵn trong fifo tại thời gian hiện tại.
** Ứng dụng của FIFOs có thể được sử dụng để đệm dữ liệu giữa một bộ xử lý hình ảnh và bus, hoặc một hệ thống truyền thông có thể sử dụng FIFOs để đệm các gói thông tin khi đi ngang qua một mạng.
*** Ví dụ trong một chương trình SystemC.
Mã:
#include <systemc.h>
SC_MODULE(example_fifo) {
void example_fifo::m_drain_packets(void);
void example_fifo::t_source1(void);
void example_fifo::t_source2(void);
// Constructor
SC_CTOR(example_fifo) {
SC_METHOD(m_drain_packets);
SC_THREAD(t_source1);
SC_THREAD(t_source2);
// Size the packet_fifo to 5 ints.
sc_fifo<int> packet_fifo (5);
}
// Declare the FIFO
sc_fifo<int> packet_fifo;
};
void example_fifo::m_drain_packets(void) {
int val;
if (packet_fifo.nb_read(val)) {
std::cout << sc_time_stamp() << ": m_drain_packets(): Received " << val <<
std::endl;
} else {
std::cout << sc_time_stamp() << ": m_drain_packets(): FIFO empty." << std::endl;
}
// Check back in 2ns
next_trigger(2, SC_NS);
}
void example_fifo::t_source1(void) {
int val = 1000;
for (;;) {
wait(3, SC_NS);
val++;
packet_fifo.write(val);
std::cout << sc_time_stamp() << ": t_thread1(): Wrote " << val << std::endl;
}
}
void example_fifo::t_source2(void) {
int val = 2000;
for (;;) {
wait(5, SC_NS);
val++;
packet_fifo.write(val);
std::cout << sc_time_stamp() << ": t_thread2(): Wrote " << val << std::endl;
}
}
int sc_main(int argc, char* argv[]) {
example_fifo ex_fifo ("ex_fifo0");
sc_start(30, SC_NS);
return 0;
}