简介

SystemC的意义,网上能查到,这里总结一下,System C是C++的library,类似UVM是systemverilog的library

下图是SystemC在整个项目中的角色

  • 硬件架构探索,创建算法、性能模型;
  • 验证工程师做为参考模型(经过DPI接口调用);
  • 设计工程师将其做为design spec,设计RTL;
  • 软件工程师做为软件开发的硬件模型;
  • 使多种提早测试成为可能

一 按照

去官网下载tar包, https://www.accellera.org/downloads/standards/systemc

我下载的是SystemC 2.3.3 (Includes TLM), Core SystemC Language and Examples (tar.gz)

在linux上安装

1.放到linux 任意路径,tar -zxvf 解包

2.在systemc-2.3.3中有一个INSTALL的文件,安装步骤就可以了

2.1 mkdir objdir; 2.2 cd objdir;  2.3 export CXX=g++ or setenv CXX g++ 2.4 ../configure --prefix=/usr/local/systemc (重新指定安装路径) 2.5 make; 2.6 make check 2.7 make install 2.9 cleean

example 测试

在安装的文件下有 example, 进入make,

如果报错的话根据提示看一下就好,遇到了TARGET_ARCH, 使用的机器是linux64, default 这个变量是空的

二 Start with example

这里写了一个简单的hello world, 并自己写了一个makefile

example: hello world

例子没什么好说的,System C电子系统设计一开始就把code show出来了

#ifndef _HELLO_H
#define _HELLO_H
#include "systemc.h"SC_MODULE(hello) {SC_CTOR(hello) {cout<<"Hello SystemC!"<<endl;}
};
#endif#include "hello.h"int sc_main(int argc, char * argv[]) {hello h("hello");return 0;
}

makefile

g++ -O2 -Wall -Werror -Wno-unused-variable -Isrc -I/user/systemc/include -c main.cpp -o main.o
g++ -O2 -Wall -Werror -Wno-unused-variable -L/user/systemc/lib-linux64 -Wl,-rpath=/user/systemc/lib-linux64 -lsystemc -lm -o com main.o

这里可能会报找不到.so, 需要加入-Wl,-rpath=xxx, 把路径指过去,或者设置环境变量LD_LIBRARY_PATH

CXX := g++
GCCVERSION := $(shell expr `gcc -dumpversion`)#FLAGS_STRICT = -pedantic -Wno-long-longDEBUG   = -g
CXXFLAGS= -O2 -Wall -Werror -Wno-unused-variable
SYSTEMC = /user/systemc
INCDIR  = -Isrc -I$(SYSTEMC)/include
LIBDIR  = -L$(SYSTEMC)/lib-linux64
LIBS    = -lsystemc -lm
RPATH   = $(SYSTEMC)/lib-linux64SRCS := $(wildcard ./*.cpp)OBJS = $(patsubst %cpp, %o, $(SRCS)) main.o%.o: %.cppecho "Compile " $< " to " $@$(CXX) $(CXXFLAGS) $(INCDIR) -c $< -o $@all: $(OBJS)$(CXX) $(CXXFLAGS) $(LIBDIR) -Wl,-rpath=$(RPATH) $(LIBS) -o $@ $^ ./allclean:rm -rf *.o *.out ./com

example: nand2 with testbench

这个例子来自于System C电子系统设计,这里记录遇到的问题

1.sc_start(100, SC_NS); // 2.3.3版本需要把clock 单位加上

2.vcd 文档打开,simvision/verdi, open database 打开就行

三 基本概念

SC_MODULE

SC_MODULE(module)

实际上SC_MODULE的code如下: #define SC_MODULE(module_name) struct module_name : public sc_module, 所以也可以使用C++的方式定义module,class module : public sc_module; 两者区别是前者默认所有的成员是public的,而后者是private的

构造函数和析构函数

1. SC_CTOR

SC_CTOR(module_name) 中定义了SC_METHOD等3个进程所需要的一些定义

2.传统C++的方式

SC_AS_PROCESS(module_name);

module_name ( sc_module_name n): sc_module(n) {...}

析构函数: ~module_name(){...}

端口

sc_in<sc_uint< 8 >> din; // sc_in< sc_logic > a[32];

sc_out<sc_uint<8>>dout;

sc_inout<sc_uint<8>> dinout;

sc_in_clk clk;

sc_signal<bool> S1, S2, S3;

方法

read() // mem[addr.read()]wr_data.read();

write()

时钟

typedef sc_in<bool> sc_in_clk; 所以sc_in_clk 跟sc_in<bool>是等价的

sc_clock 类: 参数(name, period, 时间单位, 占空比, 开始时间, 第一个逻辑是低电平还是高电平)

eg: sc_clock clk("fclk", 20, SC_NS, 0.5, 5, true);

推荐写法: 1. sc_clock clk1("clk1", 20, SC_NS); 2. sc_clock clk2("clk2", 20, SC_NS, 0.5);

基本数据类型

操作符:

, : (a, b) 将a, b 串起来, 类似位拼接

range(left, range): 位选择 a[left, range]

位减操作:and_reduce, 类似&A

任意精度整型数据类型

sc_bigint

sc_biguint

可以通过自定义SC_MAX_NBITS提高速度, 推荐SC_MAX_NBITS定义为BITS_PER_DIGIT(30)的整数倍

用户自定义结构体

typedef struct _frame {...} frame;

typedef struct _frame {unsigned short frame_constrol;char src_addr[6];char dst_addr[6];char *body;
} frame;

进程

System C 基本进程有3种

1. SC_METHOD

2. SC_THREAD

3. SC_CTHREAD

SC_METHOD

sc_method 需要敏感列表,不能使用wait()这样的语句,避免死循环,防止时间停止。 当敏感列表中有事件发生,它会被调用,调用后立刻返回。

每个clk的上升沿, main被执行一次。

SC_CTOR(tb) {SC_METHOD(main);sensitive<<clk.pos();
}

SC_THREAD

sc_thread 能够被挂起和重新激活。 sc_thread使用wait()挂起, 当敏感列表中有事件发生,进程被重新激活运行到新的wait语句,在一次仿真中thread一旦退出,将不再进入。

eg: SC_THREAD(main);

sensitive<<clk.pos();

SC_CTHREAD

Clock Thread Process, 是一种特殊的thread,继承于thread, 但是只能在时钟上升沿或者下降沿被触发。

SC_CTOR(tb){SC_CTHREAD(gen_input,clk.pos());reset_signal_is(rst_i, true);
}

wait() and next_trigger()

wait() 只能用于thread/Cthread. 参数有下面种

1.wait(); 等待敏感列表中的事件

2. wait(const sv_event&) ; 等待事件发生,eg:  sc_event e1; wait(e1);

3. wait(sc_event_or_list &); 等待事件之一发生; eg: sc_event e1, e2, e3; wait(e1|e2|e3);

4. wait(sc_event_and_list &); 等待事件全部发生;

5. wait(200, SC_NS);

6. wait(200, SC_NS, e1); 在200NS内等待e1, 如果期间等不到后,就不再等带e1

next_trigger(); 只用于SC_METHOD

dont_initialize() and sensitive

SC_METHOD and SC_THREAD必须有敏感列表, 使用sensitive设置敏感列表: sensitive<<敏感列表<<敏感列表N; sensitive<<clk.pos()<<rst_n.pos();

如果进程不希望在0时刻执行,此时可以使用dont_initialize();

SystemC 波形dump

  // trace file creationsc_trace_file * tf = sc_create_vcd_trace_file("Nand2");sc_trace(tf, N2.A, "A");sc_trace(tf, N2.B, "B");sc_trace(tf, N2.F, "F");sc_start(200, SC_NS);sc_close_vcd_trace_file(tf);

systemC 允许仿真结果dump位VCD(Value Change Dump)格式,

dump struct data需要重载sc_trace();

struct packet {char src_addr;char dst_addr;int  payload;
}void sc_trace(sc_trace_file *tf, const packet v, const string name) {int i;sc_trace(tf, v.src_addr, name+".src_addr");sc_trace(tf, v.dst_addr, name+".dst_addr");sc_trace(tf, v.payload,  name+".payload");
}

SystemC 报告机制

1.常用macro:

SC_REPORT_INFO(msg_type, msg)

SC_REPORT_WARNING(msg_type, msg)

SC_REPORT_ERROR

SC_REPORT_FATAL

sc_assert(expr)

主要使用sc_report_handler and sc_report, SC_REPORT_INFO <-> sc_report_handler::report(SC_INFO, msg_type, msg, _FILE_, _LINE_);

四 SystemC 行为建模

TLM 知识

systemc 中定义了interface, port, channel.

接口是一个C++抽象类,通道实现一个或者多个接口

接口中定义的抽象方法在通道中实现

interface

1.接口是C++抽象类

2. 接口的所有方法用“=0”标识是纯虚函数

3.C++ 不允许创建抽象类对象

4. sc_interface是所有接口的基类

5.接口不包括任何数据成员

ram interface example

enum transfer_status { TRANSFER_OK=0, TRANSFER_ERROR};
template <class T>
class mem_read_if: public sc_interface {public: virtual transfer_status read(unsigned int addr, T& data) = 0;
}
template <class T>
class mem_write_if: public sc_interface {public: virtual transfer_status write(unsigned int addr, T& data) = 0;
}
template <class T>
class reset_if: public sc_interface {public: virtual bool reset() = 0;
}
template <class T>
class mem_if: public mem_write_if<T>, mem_read_if<T>, reset_if<T> {public: virtual unsigned int start_addr() const = 0;virtual unsigned int end_addr() const = 0;
}

port(端口)

  1. sc_in<T>;
  2. sc_out<T>;
  3. sc_inout<T>;
  4. 自定义端口: sc_port<Interface Type, ChannelNumber=1>

自定义端口:

一个端口可以同时连接到一个或者多个实现了同一接口的通道上:

格式: sc_port<Interface Type, ChannelNumber=1>

sc_port<ram_if, N> ram_portN; 基类是sc_port<IF, N>;

sc_port<IF,N> 是所有端口基类

Channel (通道)

系统抽象的3个关键:

  1. 行为 -> module
  2. 时序
  3. 通信 ->  通道

通道才是接口方法的实现者

通道本身也可能是module

通道分为primitive channel 和hierarchical channel. 基本通道包括:sc_fifo, sc_signal, sc_signal_rv, sc_buffer, sc_semaphore, sc_mutex.

sc_mutex_if

互锁, class sc_mutex_if: virtual public sc_interface

sc_semaphore_if

sc_event

notify()

cancel()

eg: sc_event e; e.notify(2, SC_NS); wait(e);

TLM2

打印相关信息

  cout<<"tlm release:\n\t"<<tlm::tlm_release()<<endl;cout<<"tlm version:\n\t"<<tlm::tlm_version()<<endl;cout<<"tlm copyright:\n\t"<<tlm::tlm_copyright()<<endl;

TLM2基本组件

  1. tlm_initiator_socket 和tlm_target_socket
  2. tlm_generic_payload
  3. tlm_phase (非阻塞传送接口模板类的缺省相位类型)
  4. 阻塞和非阻塞传送接口, DMI和调试传送接口

SystemC with UVM via DPI

如果已经有DPI-C相关知识的话,这部分跟RTL-C 是一样的

verilog call C

C部分:

extern C function, 目的是为了verilog能call 这部分function, 在verilog中调用call_systemc_function, 转到SC中sc_model__called_from_sv,在转到sc_model中的input_string_extern_c

SC_MODULE( sc_model ) {...SC_CTOR( sc_model ) {...}
};//
SC_MODULE_EXPORT(sc_model)extern "C" {sc_model * sc_model__getScopeByName( const char* inst ) {sc_model* scope = NULL;scope = dynamic_cast<sc_model*>(sc_find_object(inst));vpi_printf("DPI PRINT:: sc_model__getScopeByName returning scope of sc_model\n");return scope;}void sc_model__linkSvScope( sc_model * scope ) {vpi_printf("DPI PRINT:: sc_model__linkSvScope called, giving scope of SV interface to SC model \n");scope->setScope( svGetScope() );}int sc_model__called_from_sv (sc_model *scope, const char* input_string) {vpi_printf("DPI PRINT:: sc_model__called_from_sv function called from %s\n", input_string);// the scope has been set to the right model so calling the function in that modelreturn scope->input_string_extern_c(input_string);}}

verilog

interface 中关联与SC的function

interface sc_model_if ();import uvm_pkg::*;event my_event; //*< event triggered by call by SystemC modelchandle scope; //*< C instance scope// called by interface code to get chandle for C instance scopeimport "DPI-C" pure function chandle sc_model__getScopeByName   ( input string  inst );// called by interface code to establish callback scope for modelimport "DPI-C" context function void sc_model__linkSvScope( chandle scope );// importing the functions and tasks that we need to be able to access in the SystemC modelimport "DPI-C" context task sc_model__called_from_sv   ( chandle scope, input string input_string );// exporting functions that we want the c model to be able to callexport "DPI-C" function sv_called_from_sc_model;string sc_model_hierarchy;task call_systemc_function(input string input_string);if( scope != null )sc_model__called_from_sv  ( scope, input_string );else`uvm_fatal( $sformatf("%m"), "Call to call_systemc_function before connecting to hierarchy" )endtaskfunction void sv_called_from_sc_model (input string input_string);`uvm_info($sformatf("%m"), $sformatf("function sv_called_from_sc_model called by the SystemC model with: %s", input_string), UVM_MEDIUM )`uvm_info($sformatf("%m"), "triggering event to notify the UVM environment", UVM_MEDIUM )-> my_event;endfunctiontask wait_for_event();@(my_event);// or perhaps wait(my_event.triggered()); to avoid races if its not triggered multiple times in a time stependtaskendinterface

C call verilog

C 部分

在构造函数中加入SC_THREAD

SC_MODULE(sc_model){SC_CTOR( sc_model ) {SC_THREAD(call_verilog);}void call_verilog() {ostringstream msg;msg << "Entering function call_verilog";SC_REPORT_INFO( "SYSTEMC:: ", msg.str().c_str() );wait(5, SC_NS);svSetScope(sv_if);sv_called_from_sc_model("string passed from SystemC model");}}

verilog 部分

interface sc_model_if ();import uvm_pkg::*;// exporting functions that we want the c model to be able to callexport "DPI-C" function sv_called_from_sc_model;function void sv_called_from_sc_model (input string input_string);`uvm_info($sformatf("%m"), $sformatf("function sv_called_from_sc_model called by the SystemC model with: %s", input_string), UVM_MEDIUM )`uvm_info($sformatf("%m"), "triggering event to notify the UVM environment", UVM_MEDIUM )-> my_event;endfunctionendinterface

Xcelium command:

elaborate

xrun +UVM_NO_RELNOTES -xmlibdirname tmp_xcelium.d -l gen_header.log -64bit -licqueue -sv \
-uvm -vtimescale 1ns/1ns -f filelist -elaborate \
-dpi \
-dpiheader dpi_export.h \
-dpiimpheader dpi_import.h 

run

xrun -quiet -64bit -licqueue -sv +UVM_NO_RELNOTES -uvm +UVM_VERBOSITY=HIGH \
# SystemC model
-sysc -I.
../src/sc_model.cpp
-scautoshell verilog# Verilog testbench
-vtimescale 1ns/1ns -f filelist # DPI export
-dpi#debug
-g
#-tcl
#-input debug.tcl
-linedebug
#-uvmlinedebug

SystemC with UVM via TLM2

可以先参考下面的文档

https://blog.csdn.net/ocarvb/article/details/108450311

下面网址可以下载uvmc library

https://verificationacademy.com/cookbook/uvm-connect

tips:

sc, sv 沟通的transaction可以通过uvm_object_utils来关联,但是顺序必须一样

SV to SC

一种是sv中的init直接连接sc中的target,另一种可以在tb中写一个adapter,使用passthrough做切割

1. uvm agent monitor中发出command

class my_monitor extends uvm_component;`uvm_component_utils(my_monitor)uvm_tlm_b_initiator_socket#(uvm_tlm_generic_payload) init_skt;function void build_phase(uvm_phase phase);super.build_phase(phase);init_skt = new("init_skt", this);endfunctiontask run_phase(uvm_phase phase);super.run_phase(phase);uvm_tlm_generic_payload gp;uvm_tlm_time delay;byte unsigned wdata[];......gp = uvm_tlm_generic_payload::type_id::create("gp");delay = new("delay");wdata = new[`CRB_DATA_WIDTH/8];wdata = {<<byte{vif.monclk.wdata}};gp.set_address(vif.monclk.addr);gp.set_data(wdata);init_skt.b_transport(gp, delay);endtask
endclass

2. 在env将init socket 连接到SC层

adapter:class b_socket_barrier #(type T=uvm_tlm_generic_payload) extends uvm_component;`uvm_component_param_utils(xxx_b_socket_barrier#(T))uvm_tlm_b_target_socket#(xxx_b_socket_barrier#(T),T) tgt_skt;uvm_tlm_b_initiator_socket#(T) init_skt;virtual task b_transport(T obj,uvm_tlm_time dly);init_skt.b_transport(obj,dly);endtask
endclassenv:
uvmc_pkg::uvmc_tlm#(uvm_tlm_generic_payload)::connect(agt.monitor.init_skt,"sv2sc_cmd");

3.在SC中实现socket, main中connect, 在module中通过register_b_transport 指定执行哪个function

#include "systemc.h"
using namespace sc_core;
using namespace sc_dt;
using namespace std;
#include "tlm.h"
using namespace tlm;class top_module : public sc_module{
public:top_module (sc_module_name name); // constructuretlm_utils::simple_target_socket<top_module> cmd_in;
}SC_HAS_PROCESS(top_module);top_module::top_module(sc_module_name name) : sc_module(name),cmd_in("cmd_in")
{cmd_in.register_b_transport(this,&top_module::cmd_b_transport);}void top_module::crb_b_transport(tlm_generic_payload &c, sc_time &t) { ... }int sc_main(int argc, char* argv[]) {top_module top("top");uvmc_connect(top.cmd_in,"sv2sc_cmd");
}

SC 2 SV

1. SC 部分

module top;
multi_passthrough_initiator_socket<cls_name, 32, struct> out;
function:xxxxcmd.data = xxx;out->b_transport(cmd, t);
int sc_main(int argc, char* argv[]) {...uvmc_connect(top.out, "out_0");
}

2. SV中接收

adapter:
class tlm2_to_tlm1_b_socket_barrier #(type T=uvm_tlm_generic_payload) extends uvm_component;`uvm_component_param_utils(tlm2_to_tlm1_b_socket_barrier#(T))uvm_tlm_b_target_socket#(tlm2_to_tlm1_b_socket_barrier#(T),T) tgt_skt;uvm_analysis_port #(T) m_ap;task b_transport(T obj,uvm_tlm_time dly);m_ap.write(obj);endtask
endclassmodel:
uvm_analysis_port#(item) ap;
barrier.m_ap.connect(ap);
uvmc_pkg::uvmc_tlm#(item)::connect(barrier.tgt_skt,"out_0");env:
model.ap.connect(m_scb.output_sb.expected_trans_fifo.analysis_export);

完整example

C code:

// because of dpi, so the code is not clean
#include <iostream>
#include "dpi_export.h"
#include "systemc.h"
#include "tlm.h"
#include "tlm_utils/simple_initiator_socket.h"
#include "tlm_utils/simple_target_socket.h"
#include "../uvmc-2.3.2/src/connect/sc/uvmc.h"//using namespace tlm;
using namespace sc_core;
using namespace sc_dt;
using namespace std;
using namespace uvmc;
using namespace tlm;SC_MODULE( sc_model ) {tlm_utils::simple_initiator_socket<sc_model> out;tlm_utils::simple_target_socket<sc_model> in;SC_CTOR( sc_model ) : out("out"), in("in") {in.register_b_transport(this, &sc_model::in_b_transport);//SV to SCSC_THREAD( call_tlm_c2v   ); // SC to SVmsg << "System C model constructed" << name();SC_REPORT_INFO( "SYSTEMC:: CONSTRUCTOR:: ", msg.str().c_str() );}void call_tlm_c2v() {tlm::tlm_generic_payload* trans = new tlm::tlm_generic_payload;sc_time delay = sc_time(10, SC_NS);int data;cout<<"SC: start call c2v"<<endl;wait(delay); // for uvm connect phasefor (int i = 32; i < 36; i += 4) {tlm::tlm_command cmd = static_cast<tlm::tlm_command>(rand() % 2);if (cmd == tlm::TLM_WRITE_COMMAND) data = 0xFF000000 | i;trans->set_command(cmd);trans->set_address(i);trans->set_data_ptr( reinterpret_cast<unsigned char*>(&data) );out->b_transport(*trans, delay);//if (trans->is_response_error())//  SC_REPORT_ERROR("TLM-2", "Response error from b_transport");cout<<"SC:transport done"<<endl;}} virtual void in_b_transport(tlm_generic_payload& trans, sc_time& delay) {tlm::tlm_command cmd = trans.get_command();sc_dt::uint64  adr = trans.get_address();unsigned char*   ptr = trans.get_data_ptr();//unsigned int     len = trans.get_data_length();//unsigned char*   byt = trans.get_byte_enable_ptr();//unsigned int     wid = trans.get_streaming_width();cout<<"SC: b_transport addr="<<adr<<endl;//trans.set_response_status(tlm::TLM_OK_RESPONSE);//if (trans->is_response_error() )//  SC_REPORT_ERROR("TLM-2", "Response error from b_transport");}// sc_main
int sc_main(int argc, char* argv[]) {cout<<"sc_main"<<endl;sc_model sc("sc_model");uvmc_connect(sc.out, "out");uvmc_connect(sc.in, "in");sc_start();return 0;
};

SV code:

// the uvm agent is ready, here put all code on uvm_test
`include "uvm_macros.svh"
import uvm_pkg::*;
import uvmc_pkg::*;class my_uvm_test extends uvm_test;`uvm_component_utils(my_uvm_test)uvm_tlm_b_initiator_socket#(uvm_tlm_generic_payload) ini_skt;uvm_tlm_b_target_socket#(my_uvm_test, uvm_tlm_generic_payload) tgt_skt; function void build_phase (uvm_phase phase);ini_skt= new("ini_skt", this);tgt_skt = new("tgt_skt",this);endfunction // build_phasefunction void connect_phase(uvm_phase phase);uvmc_pkg::uvmc_tlm#(uvm_tlm_generic_payload)::connect(tgt_skt, "out");uvmc_pkg::uvmc_tlm#(uvm_tlm_generic_payload)::connect(ini_skt, "in");$display("connect done");endfunction// SC to SV, if have multi socket, can add a adapter class, and instance adapters// eg: uvmc_pkg::uvmc_tlm#(payload)::connect(barrier0.tgt_skt,"out_0");//     uvmc_pkg::uvmc_tlm#(payload)::connect(barrier1.tgt_skt,"out_1");//     b_transport is implement on the barrier classtask b_transport(uvm_tlm_generic_payload obj,uvm_tlm_time dly);$display("SV: b_transport, addr=%0d", obj.get_address());//obj.set_response_status(tlm::TLM_OK_RESPONSE);endtasktask run_phase(uvm_phase phase);phase.raise_objection(this);beginuvm_tlm_generic_payload gp;uvm_tlm_time delay;byte unsigned wdata[];gp = uvm_tlm_generic_payload::type_id::create("gp");delay = new("delay");wdata = new[1];wdata = {<<byte{5}};gp.set_address(16);gp.set_data(wdata);ini_skt.b_transport(gp, delay);$display("SV: transfer");end#2000;phase.drop_objection(this);endtaskendclass: my_uvm_test

xcelium command:

xrun -quiet -64bit -licqueue-sv -mess -define DENALI_SV_NC -define DENALI_UVM
-uvmhome CDNS-1.1d
-loadvpi /tools/cadence/vip/11.30.066/tools.lnx86/denali_64bit/verilog/libcdnsv.so:cdnsvVIP:export
-top tb_top
-v2001
+UVM_NO_RELNOTES-uvm +UVM_VERBOSITY=HIGH-sysc -sc_main -I. ../src/sc_model.cpp -scautoshell verilog -DSC_INCLUDE_DYNAMIC_PROCESSES-vtimescale 1ns/1ns ../src/my_pkg.sv -f uvmc-pkg.f ../src/tb_top.sv-dpi  -g  

SystemC Study相关推荐

  1. Oracle Study之--Oracle等待事件(3)

    Oracle Study之--Oracle等待事件(3) Db file parallel read 这是一个很容易引起误导的等待事件,实际上这个等待事件和并行操作(比如并行查询,并行DML)没有关系 ...

  2. 读书笔记2013第10本:《学得少却考得好Learn More Study Less》

    <学得少却考得好Learn More Study Less>这本书最早是从褪墨网站上看到的,crowncheng翻译了全文.这本书介绍了不少学习方法,非常适合在校的学生,原文的作者Scot ...

  3. Case study:在数据库网页中设计数据排序工具

    一.目的 该笔记的目的是引导读者在已搭建的数据库网页的基础上,利用JS设计数据排序工具.其效果如图1所示."Order by"下拉列表框由一系列字段组成,如"Locati ...

  4. Case Study: 利用PHP获取关系型数据库中多张数据表的数据

    一.目标 该笔记的目的是引导读者借助WampServer平台和MySQL数据库,利用HTML/CSS/JS/PHP设计一个多数据表关联的网页.在上一个案例(Case Study: 利用JS实现数据库网 ...

  5. Case Study: 利用JS实现数据库网页的数据分页、数据选择、数据详细信息查看功能

    一.目标 该笔记的目的是引导读者借助WampServer平台和MySQL数据库,利用HTML/CSS/JS/PHP设计一个能够进行实现数据分页显示.数据选择.数据详细信息查看功能的数据库网页.该数据库 ...

  6. Case Study: 利用JS设计高级检索功能通过PHP获取MySQL数据

    一.目标 该笔记的目的是引导读者借助WampServer平台和MySQL数据库,利用HTML/CSS/JS/PHP设计一个含有高级检索功能的数据库网页.该功能效果如图1所示.用户在文本框中输入相应内容 ...

  7. QIIME 2用户文档. 5粪菌移植分析练习Fecal microbiota transplant (FMT) study

    文章目录 前情提要 QIIME 2用户文档. 5粪菌移植分析练习 启动QIIME2运行环境 实验数据下载 序列质控评估 生成特征表和代表性序列 查看去噪过程统计 合并不同批的代表序列和特征表 表1. ...

  8. 二值网络训练--A Empirical Study of Binary Neural Networks' Optimisation

    A Empirical Study of Binary Neural Networks' Optimisation ICLR2019 https://github.com/mi-lad/studyin ...

  9. oracle顺序读等待,Oracle Study之--Oracle等待事件(4)

    Oracle Study之--Oracle等待事件(4) Db file scattered read这个等待事件在实际生产库中经常可以看到,这是一个用户操作引起的等待事件,当用户发出每次I/O需要读 ...

  10. OS study plan

    From now on, I will study the Minix source code. There may be 6 months long. Plan: 1. Analysis Minix ...

最新文章

  1. nginx与php-fpm通讯方式
  2. 如何使用matplotlib绘制一个函数的图像
  3. 背水一战 Windows 10 (15) - 动画: 缓动动画
  4. SAP CRM Fiori应用Simulation pipeline的刷新问题
  5. python学习-综合练习五(五人分鱼(优化解)、顺向、反向推导)
  6. Microwindows及基于Nano-X的简单程序开发
  7. Acwing 271. 杨老师的照相排列
  8. ant 路径_在Ant中显示路径
  9. PingCAP创始人刘奇:TiDB设计理念进化与大规模实践
  10. Atitit 查找轮廓 findContours
  11. 【转载】VGA视频信号详解
  12. apk反编译 (com.googlecode.d2j.DexException: not support version问题解决)
  13. 关于腾讯云短信sms接口自定义API写法 PHPdemo
  14. 【精选】VI手册设计模板合集,附带源文件、预览图、精细分类
  15. linux五笔输入法制作_在linux下制作拼音五笔输入法
  16. flutter APP自动更新
  17. SpringCloud 微服务(一)
  18. 企业微信如何建立部门?
  19. Java中变量与常量
  20. 数据备份一般有哪些方式,如何进行数据备份

热门文章

  1. GPS测量中所涉及的时间系统
  2. 自动驾驶操作系统现状与发展趋势
  3. 测试方案的设计及模板
  4. 使用AdventNet快速开发网管软件Agent端
  5. 黑客都使用什么编程语言?
  6. 使用SCM管理jenkinsfile
  7. 如何使用USGS下载DEM数据
  8. HADOOP学习_grep和wordcount的例子
  9. 信息检索的过去 当前 未来-------浅层分析报告
  10. 腾讯X5内核浏览器的使用