Tiago Salmito mahatma@natalnet.br SystemC 2.0.1 Tiago Salmito mahatma@natalnet.br.

Slides:



Advertisements
Apresentações semelhantes
TIPOS ABSTRATOS DE DADOS
Advertisements

Análise e Projeto de Sistemas I
Curso de aprofundamento na linguagem C
ABSTRAÇÃO processo de representar um grupo de entidades através de seus atributos comuns feita a abstração, cada entidade particular (instância) do grupo.
Sistemas Digitais Projeto RTL – Unidade de Controle
Introdução à Ciência da Computação Linguagens de Programação.
Adélia Barros Testes de Software Adélia Barros
Curso: Banco de Dados I Análise de Sistemas PUC Campinas
Algoritmo e Programação
UML Modelando um sistema.
UML Visões – Parte 2.
UNIVERSIDADE ESTADUAL DE MATO GROSSO DO SUL SISTEMAS DE INFORMAÇÃO ENGENHARIA DE SOFTWARE Métricas de Software Prof.ª Adriana dos Santos Caparróz Carvalho.
(Unified Modeling Language)
Projeto conceitual Mostra ao cliente exatamente o que o sistema fará
O Essencial sobre Linguagens de Programação Luís Caires Maio 2005.
GAPH - PPGCC - FACIN - PUCRS
Unidades de Execução e de Controle Sistemas Digitais.
VHDL AULA - 2.
Faculdade de Ciências Sociais e Aplicadas de Petrolina – FACAPE
Metodologias Orientadas a Agentes
Descrição de hardware em SystemC
CAD (Caco Aided Design)
Curso Sistemas de Informação Disciplina: Arquitetura de Software
Análise Estruturada O mais amplamente usado dos métodos de modelagem de requisitos Modelos que retratam fluxo e o conteúdo da informação (dados e controle)
TIPOS DE TESTES APLICÁVEIS E NÃO APLICÁVEIS AO PROJETO
Aspectos Avançados em Engenharia de Software Aula 3 Fernanda Campos
Classes e objetos P. O. O. Prof. Grace.
Estrutura de Dados em Java
DIAGRAMA DE COMPONENTES
Copyright Marcos L. Chaim 2005 Princípios de Projeto de Software Orientado a Objetos Segundo Semestre 2005 Marcos L. Chaim ACH Turma 02 EACH – USP.
JAVA: Conceitos Iniciais
REDUNDÂNCIA POR SOFTWARE
PROGRAMAÇÃO I UNIDADE 1.
Antonyus Pyetro Infra-estrutura de Hardware – IF674
Programação Avançada Prof. Natalia Castro Fernandes
JAVA Linguagem Ambiente de Desenvolvimento
METODOLOGIA PARA DESENVOLVIMENTO DE SISTEMAS Prof. Dr. rer. nat. Daniel D. Abdala 1.
Carlos Oberdan Rolim Ciência da Computação
Análise e Projeto de Sistemas
Linguagem C++ - Introdução
Algoritmos e Programação de Computadores
Linguagem de Programação JAVA
Christien Lana Rachid6.1d.1 Técnica de BD - Dicionarização UNIPAC 2º SEMESTRE 2007.
Tipos Abstratos de Dados
Classes, Objetos, Atributos e Métodos JAVA
Orientação a Objetos Parte I
Desenvolvimento de Jogos e Entretenimento Digital Oficina temática: Algoritmos e Programação Orientação a Objetos: herança Professor: Sandro Rigo.
Estruturas de Dados Aula 8: Tipos Abstratos de Dados 30/04/2014.
Sistemas lineares Aula 1 - Sinais.
O que é? É o processo de investigação técnica com intuito de identificar a qualidade, a segurança e a exatidão do software desenvolvido. A validação do.
Programação de PIC em C Exposição das funções básicas para
Testes de Software AULA 03 Eduardo Silvestri
RUP - Cap. 3 – Processo Dirigido por Caso de Uso
Métodos Formais.
BRAZIL IP The BrazilIP Network SystemVerilog para Verificação funcional com OVM Curso do Brazil-IP Elmar Melcher UFCG
Hardware Description Language Aula 9 –Verilog HDL Prof. Afonso Ferreira Miguel, MSc.
Linguagens de Programação
A Linguagem Formal de Especificação VDM-SL
VERILOG.
VERILOG Monitoria Infra-Estrutura de Hardware Álvaro João – ajss Húgaro Bernardino – hbb Fred Rabelo - ferrf Leonardo Leandro – lsl2 Jéssica de.
Introdução a VHDL Monitoria de Digitais.
Aula Prática 13 Orientação a Objeto Monitoria
Engenharia de Requisitos
Padrões de projeto M.Sc. Sílvio Bacalá Jr..
Análise e Projeto de Sistemas Orientado a Objetos Profa. Ana Karina Barbosa.
Módulo II Capítulo 1: Orientação a Objetos
ISO9001:2000 para Software Professor: Alexandre Vasconcelos Equipe: Amanda Pimentel Börje Karlsson Danielly Karine Erika Pessoa Jorge Cavalcanti Jose Edson.
Influencias sobre o Projeto da Linguagem
Tipos Compostos Heterogêneos e Tipos Abstratos de Dados
Estrutura de Dados Prof. André Cypriano M. Costa
Transcrição da apresentação:

Tiago Salmito mahatma@natalnet.br SystemC 2.0.1 Tiago Salmito mahatma@natalnet.br

SystemC Biblioteca de classes para C++. Suporta o co-design do hardware-software e a descrição da arquitetura de sistemas complexos que consistem de componentes de software e hardware. Serve para criar a "especificação executável" de um sistema.

Por que C? C++ provê a abstração de controle e de dados necessários para descrição de sistemas. A orientação a objeto e as macros do C++ nos permite estender a linguagem com classes, sem mudar a sua sintaxe.

Benefícios da "Especificação Executável" Evitar inconsistências, erros e garantir a completude do sistema; Assegurar uma interpretação não ambígua para a especificação do sistema. Verificar a funcionalidade do sistema antes do inicio da sua implementação. Criar modelos de performance do sistema, ou validar a performance do sistema. Os casos de testes usados na EE podem ser usados no teste da implementação do sistema. O exato comportamento do sistema pode ser validado usando-se o Waveform Tracing.

Definições Módulos: São entidades hierárquicas onde podem conter outros módulos ou processos. Processos: São usados para descrever as funcionalidades dos módulos. Portas: Módulos possuem portas nas quais o conecta a outros módulos. Podem ser unidirecionais ou bidirecionais. Sinais: São usados para se conectar portas (fios). Podem ser controlados por um (unresolved) ou vários (resolved) drivers. Clocks: É um sinal especial usado para a sincronização do sistema durante a simulação.

Metodologia de design sem SystemC

Metodologia de design com SystemC

SystemC 1.0 - Módulos São os blocos de construção básicos no SystemC para particionar o design. Eles encapsulam as representações dos dados internos e algoritmos de outros módulos. São declarados: Com a Macro: SC_MODULE(nome) { ... }; Usando OO: struct nome : sc_module { ... }; Um módulo pode conter diversos outros atributos como portas, sinais locais, dados locais, outros módulos, e construtores. O construtor é declarado com a macro: SC_CTOR(nome_do_modulo) { ... }

Módulos: Portas Passam dados de (ou para) processos de um módulo. Podem ser declaradas de 3 maneiras: Entrada - sc_in<tipo> nome; Saída - sc_out<tipo> nome; Entrada/Saída - sc_inout<tipo> nome; Os tipos das portas podem ser qualquer tipo do C++, do SystemC ou tipos definidos pelo usuário. Exemplo: Flip Flop D SC_MOLDULE(dff) { sc_in<bool> din; sc_in<bool> clock; sc_out<bool> dout; ... };

Módulos: Sinais Representam os fios que interconectam os dispositivos de mesma hierarquia na implementação física do sistema. Sinais carregam dados, e pode ser conectado a várias portas. Exemplo: Filtro

Módulos: Maneiras de conectar sinais "Positional mapping" SC_CTOR(filtro) { s1 = new sample ("s1"); (*s1)(q,s); c1 = new coeff ("c1"); (*c1)(c); m1 = new mult ("m1"); (*m1)(s,c,q); } "Named mapping" SC_CTOR(filtro) { s1 = new sample ("s1"); s1->din(q); s1->dout(s); c1 = new coeff ("c1"); c1->out(c); m1 = new mult ("m1"); m1->a(s); m1->b(c); m1->q(q); }

Módulos: Armazenamento interno de dados #include "systemc.h" SC_MODULE(count) { sc_in<bool> load; sc_in<int> din; sc_in<bool> clock; sc_out<int> dout; int count_val; //armazenamento void count_up() { if (load) { count_val = din;} else { count_val++; } dout = count_val; } SC_CTOR(count) { SC_METHOD(count_up); sensitive_pos << clock; } }; Para isso o designer precisa apenas declarar variáveis locais aos módulos. Podem ser de qualquer tipo do C++, do SystemC ou definidos pelo usuário. Exemplo:

Módulos: Processos O verdadeiro trabalho dos módulos são feitos em processos. Processos são funções registradas no kernel do SystemC e são sensíveis a sinais. São "executados" a qualquer troca de valor do sinal na qual o processo é sensível. Exemplo: #include "systemc.h" SC_MODULE(dff) { sc_in<bool> din; sc_in<bool> clock; sc_out<bool> dout; void doit() { dout = din; } SC_CTOR(dff) { SC_METHOD(doit); sensitive_pos << clock; } };

Módulos: Construtor É executado sempre que houver uma instanciação a um módulo. Define a estrutura de processos no kernel do SystemC e inicializa as variáveis internas. Exemplo: SC_MODULE(ram) { sc_in<int> addr; sc_in<int> datain; sc_in<bool> rwb; sc_out<int> dout; int memdata[64]; // memoria local int i; void ramread(); //processos void ramwrite(); SC_CTOR(ram){ SC_METHOD(ramread); sensitive << addr << rwb; SC_METHOD(ramwrite) sensitive << addr << datain << rwb; for (i=0; i++; i<64) { memdata[i] = 0; } };

Módulos: Casos de teste São feitos através de módulos que geram estímulos e módulos que checam se a saída é coerente com a pós-condição

Processos São a unidade básica de execução no SystemC, são chamados para simular o comportamento do dispositivo ou sistema. Existem 3 tipos de processos: Métodos (SC_METHOD) Threads (SC_THREAD) Clocked Threads (SC_CTHREAD) Não são hierárquicos. Possuem uma lista de sensitividade e para estimular um processo deve-se ocorrer um evento.

Processos: Métodos (SC_METHOD) Executam quando ocorre um evento e retornam ao final da execução para o kernel do SystemC. SC_MODULE(mux2) { //mux de 2 portas sc_in<bool> pin1; sc_in<bool> pin2; sc_in<bool> controle; sc_out<bool> pout; void fazer() { if(controle==0) pout=pin1; else pout=pin2; }   SC_CTOR(mux2) { SC_METHOD(fazer); sensitive << pin1; sensitive << pin2 << controle; pout.initialize(true); } };

Processos: Threads (SC_THREAD) Executam indefinidamente e podem ser suspendidas e reativadas. Podem executar o comando wait() para suspender. São o são o caso mais geral de processo e podem ser usados para praticamente tudo. Threads são implementados usando co-rotinas e a biblioteca do SystemC. Exemplo: Sinal de transito. SC_THREAD(sinal);

Processos: Clocked Threads (SC_CTHREADS) São um caso especial de Threads. São usados para criar maquinas de estado implícitas. Um estado é definido entre dois comandos wait() ou wait_until(). Só pode ser sensível ao clock. Exemplo: Um controlador de barramento.

Diferenças entre threads e clocked threads O processo Cthread especifica um objeto do tipo clock. Cthread não possui lista de sensitividade. A instrução wait_until só pode ser chamada através de um processo Cthread. Um uso para o wait_until: wait_until(sensor.delayed() == true);

Processos: Watching Watching só pode ser usado por um processo Cthread. Processos Cthread são loops infinitos. Watching é a maneira de se controlar o loop. Exemplo: SC_CTHREAD(gen_data, clk.pos()); watching(reset.delayed() == true);

Portas e Sinais: Para ler sinais das portas: Use os métodos read() ou write() das portas ou o operador de atribuição. -Se precisar fazer conversões de tipo use os métodos read() e write();

Portas e Sinais: Resolved Logic Vectors São usados para sinais que possuem mais de um driver. Declarando a porta: sc_inout_rv<n> x; Declarando o sinal: sc_signal_rv<n> x; Exemplo:

Conectando sinais e portas Para conectar uma porta a um sinal eles devem ser do mesmo tipo. Se for entre portas de mesmo nível de abstração: Deve-se usar sinais. Usa-se os métodos de “positional” ou “named mapping” Se for entre portas de níveis diferente. Não necessita de sinal (porta a porta). Usa-se o método “named mapping”

Clocks É um objeto especial do SystemC. Para criar um sinal de clock: sc_clock clock(“nome”, 20, 0.5, 0, true); Para se acessar o sinal de clock usa-se o método clock.signal();

Tipos de dados do SystemC sc_bit –2 value single bit type sc_bit v=‘1’; sc_bit f=‘0’; sc_logic – 4 value single bit type sc_logic l=‘Z’; l=‘X’; l=

Tipos de dados do SystemC sc_int – 1 to 64 bit signed integer type sc_int<40> int_de_40bits; sc_uint – 1 to 64 bit unsigned integer type sc_uint<22> uint_de_22bits; sc_bigint – arbitrary sized signed integer type sc_bigint<128> b; sc_biguint – arbitrary sized unsigned integer type

Tipos de dados do SystemC sc_bv – arbitrary sized 2 value vector type sc_bv<10> vetor_de_10_bits=“1110110010”; sc_lv – arbitrary sized 4 value vector type sc_lv<70> vetor_de_3_bits=“ZX01”;

Tipos de dados do SystemC Tipos definidos pelo usuário: Exemplo: struct tipo_pacote { long info; int seq; int reenvios; inline bool operator == (const tipo_pacote& rhs) const { return (rhs.info == info && rhs.seq == seq && rhs.reenvios == reenvios); } };

Simulação A instanciação dos módulos é feita na rotina sc_main(); Após instanciar e conectar os módulos aos sinais, é feita uma chamada a função sc_start(double); A simulação pode ser parada, através da função sc_stop(); Pode-se saber o tempo atual de simulação através da função double sc_simulation_time(); Para ajudar no debug, todos as variáveis, portas e sinais podem ter seus sinais lidos e impressos.

Simulação avançada O SystemC te dá a opção de controlar o controle de sinais assincronamente. Criar seu próprio clock. Criar sinais assíncronos para teste do sistema. É feito através das performativas sc_initialize() e sc_cycle(); Exemplo: sc_signal<bool> clock; ...; sc_initialize(); for (int i = 0; i <= 200; i++) clock = 1; sc_cycle(10); clock = 0; sc_cycle(10); } Equivale à: sc_clock clk(“meu clock”, 20, 0.5); sc_start(200);

Traçando Formas de Ondas SystemC pode criar arquivos nos formatos: VCD (Value Change Dump) ASCII WIF (Waveform Intermediate Format) ou ISDB (Integrated Signal Data Base) As formas de onda geradas podem ser visualizadas com qualquer software que suporte esses formatos. Podem ser traçadas: Somente variáveis que estão no escopo durante toda a simulação. Sinais escalares, vetores ou de tipos agregados.

Traçando Formas de Ondas Criando arquivos: sc_trace_file * my_trace_file; my_trace_file = sc_create_vcd_trace_file(“my_trace”); Fechando arquivos sc_close_vcd_trace_file(my_trace_file); Traçando variáveis e sinais escalares: sc_trace(my_trace_file, var, “Variável”); O primeiro argumento e um arquivo do tipo sc_trace_file. O segundo argumento é uma referencia a variável a ser traçada. O terceiro é uma string de referência.

Traçando Formas de Ondas Exemplo: sc_signal<int> a; float b; sc_trace(trace_file, a, “MyA”); sc_trace(trace_file, b, “B”); Traçando variáveis de tipo agregado: struct bus { unsigned end; bool read_write; unsigned dado; }; void sc_trace(sc_trace_file *tf, const bus& v, const sc_string& NAME) { sc_trace(tf, v.end, NAME + “.end”); sc_trace(tf, v.read_write, NAME + “.rw”); sc_trace(tf, v.dado, NAME + “.dado”); }

Traçando Formas de Ondas Traçando vetores: void sc_trace(sc_trace_file *tf, sc_signal<int> *v, const sc_string& NAME, int len) { char stbuf[20]; for (int i = 0; i< len; i++) { sprintf(stbuf, “[%d]”, i); sc_trace(tf, v[i], NAME + stbuf); }

Pequeno Exemplo: Módulos #include <systemc.h> SC_MODULE(produtor) { sc_out<int> dout; sc_in<bool> clock; int dado; void produz() { dout = dado++; } SC_CTOR(produtor) { SC_METHOD(produz); sensitive_pos << clock; dado=0; }; SC_MODULE(consumidor) { sc_in<int> din; void consome() { int tmp=din; printf(“Dado = %d”,tmp); } SC_CTOR(consumidor) { SC_METHOD(consome); sensitive << din; };

Pequeno Exemplo: Juntando módulos #include “modulos.h” int sc_main(int argdc, char ** argc) { sc_signal<int> barramento; sc_clock clk(“clock”, 20); produtor p(“produtor”); p.dout(barramento); p.clock(clk); consumidor c(“consumidor”); c << barramento; sc_trace_file * tf=sc_create_vcd_trace_file”(“produtor_consumidor”); sc_trace(tf, barramento, “Barramento"); sc_trace(tf, clk.signal(), “Clock"); sc_start(-1); }

Estendendo o SystemC – SystemC 2.0 A descrição estrutural do SystemC é suficiente para modelar sistemas (portas e módulos). Porem a comunicação e a sincronização não é geral o suficiente para modelar em todos os níveis de sistema. O SystemC 2.0 introduz novos conceitos para preencher essa lacuna. Canais Interfaces Eventos

Tempo relativo vs Tempo absoluto Definição do clock: SystemC 1.0: sc_clock clk( “clk”, 20 ); SystemC 2.0: sc_clock clk( “clk”, 20, SC_NS ); ou sc_time t1( 20, SC_NS ); sc_clock clk( “clk”, t1 ); SC_FS – femtoseconds SC_PS – picoseconds SC_NS – nanoseconds SC_US – microseconds SC_MS – milliseconds SC_SEC – seconds Para se setar a unidade de tempo: sc_set_default_time_unit( 1, SC_PS ); (deve ser uma potência de 10)

Eventos - SystemC 2.0 Processos são sensíveis a eventos O caso do SystemC 1.0 (portas) são um caso especial. Wait() agora recebe o evento a ser esperado (lista de sensibilidade dinâmica) wait( e1 | e2 | e3 ); wait( 200, SC_NS ); wait( 200, SC_NS, e1 | e2 | e3 ); wait(); //systemc 1.0 sc_event my_event; my_event.notify(); //notifica agora my_event.notify( 10, SC_NS ); //notifica em 10 nanosegundos my_event.notify( SC_ZERO_TIME ); //proximo delta-cycle

Interfaces – SystemC 2.0 Definem métodos a serem implementados em um canal: template <class T> class sc_read_if : virtual public sc_interface { public: virtual const T& read() const = 0; }; Métodos de sc_interface: void register_port( sc_port_base&, const char* ) Usado para verificação quando se conecta uma porta a essa interface. const sc_event& default_event() Usado para a sensibilidade estática do SystemC 1.0.

Portas – SystemC 2.0 Possuem interfaces. Exemplo de porta: Exemplo: sc_in<tipo> possui a interface sc_read_if. Exemplo de porta: template <class T> class meu_sc_in: public sc_port<sc_read_if<T> > { public: operator const T&() const { return (*this)->read(); } }; Uma porta deve possuir pelo menos uma interface.

Canais – SystemC 2.0 Um canal implementa uma ou mais interfaces: Exemplo de canal: sc_signal é um canal que implementa as interfaces if_read e if_write. Porém o sc_signal só pode possuir uma porta de saída conectada. (essa verificação é feita no método register_port()). Exemplo: Canal sc_fifo: Só pode ter uma porta de entrada e uma de saída (nenhuma bidirecional).

Canais: sc_fifo O método register_port verifica as condições de conexão dos canais. template <class T> void sc_fifo<T>::register_port( sc_port_base& port,const char* if_typename ) { sc_string nm( if_typename ); if( nm == typeid( inout_interface<T> ).name() ) { error( “cannot connect to a bi-directional port” ); } else if( nm == typeid( in_interface<T> ).name() ) { if( no input port registered so far ) input_port = port; else error( “cannot connect to multiple inputs” ); } else { // nm == typeid( out_interface<T> ).name() if( no output port registered so far ) output_port = port; else error( “cannot connect to multiple outputs” ); }

Implementando Canais O método update() de um canal irá ser chamado na fase de atualização dos canais. É a hora de se determinar se há algum evento a ser gerado. Exemplo de update: sc_signal virtual void update() { if( !( m_new_val == m_cur_val ) ) { m_cur_val = m_new_val; m_value_changed_event.notify( SC_ZERO_TIME ); }

Pequeno Exemplo: Canais – sc_signal template <class T> class sc_signal: public sc_prim_channel, public sc_signal_inout_if<T> { public: sc_signal() : m_output( 0 ), m_driver( 0 ) {} virtual void register_port( sc_port_base& port, const char* if_typename ) { sc_string nm( if_typename ); if( nm == typeid( sc_signal_inout_if<T> ).name() ) { // a write or read/write port; only one can be connected if( m_output != 0 )error( “more than one write port\n” ); m_output = &port; } // any number of read ports can be connected: no check needed virtual const T& read() const { return m_cur_val; } virtual const sc_event& default_event() const{ return m_value_changed_event; } virtual void write( const T& value ) { // dynamic design rule checking if( current_process() != m_driver ) { if( m_driver == 0 ) m_driver = current_process(); else error( “more than one driver\n” ); } m_new_val = value; if( m_new_val != m_cur_val ) request_update();

Pequeno Exemplo: Canais – sc_signal protected: virtual void update() { if( !( m_new_val == m_cur_val ) ) { m_cur_val = m_new_val; m_value_changed_event.notify(SC_ZERO_TIME ); //notifica no próximo delta-cycle } sc_port_base* m_output; // for static design rule checking sc_process_b* m_driver; // for dynamic design rule checking T m_cur_val; T m_new_val; sc_event m_value_changed_event;

Fim