How to write a very simple instruction set with the following requirements? - cpu-architecture

I am very new to coding.
I am trying to understand how to write an instruction set, that is very simple.
the requirement are these basics: read, write, add, subtract,enable loop/conditional operation.
I was trying to find example codes, online but without any success.
Does the programming language has to be machine code or can it be c?

An ISA is a programming language. The programs are machine code.
An ISA is a set of rules for what exactly happens to the architectural state of the machine when running each possible instruction. e.g. binary 0101 xxyy might be a 2-operand add x,y instruction, where xx is a 2-bit destination register number, and yy is the source register number. The ISA would include rules for how flags are set, if you have a flag / condition-code register.
You don't write an ISA in another programming language.
You can design CPU hardware that implements the ISA (e.g. in verilog or VHDL I think). You can even simulate that design running a program written in machine code for your new ISA.
You can also write an interpreting emulator for that ISA, for example in C, which models the architectural state of the machine in C variables and an array for memory. The program would read machine code and decode instructions. Normally you'd design the ISA first, and then implement an emulator for it.
Another useful tool is an assembler, which translates text into machine code for your ISA. Text mnemonics for instructions and text register names only exist in the asm source.
Typically an ISA will standardize this, too, so it's possible to talk about machine code, but having an assembly language at all is not strictly necessary as part of an ISA. You can leave it up to users of the ISA to make up register names and mnemonics, and asm source syntax, for your ISA.

Related

Questions regarding address binding

There are three different address binding techniques :
Compile time binding
Load time binding
Run time binding
I have many questions regarding them :
1- According to my understanding, every OS uses a certain address binding technique to implement. Modern OSes uses run time binding and MS-DOS uses Compile time binding. Is that right ? Or the programmer can select which address binding to use ?
2- At compile time binding is used if the compiler knows in advance where the program will resides in main memory. How do the compiler know this future information ? Is it given by the programmer ?
3- Run time binding is used if the program will always change his location during execution time . Is for example swapping and segmentation compaction are examples why the programs will change their location during execution , or they are different concepts here ?
1- According to my understanding, every OS uses a certain address binding technique to implement. Modern OSes uses run time binding and MS-DOS uses Compile time binding. Is that right ? Or the programmer can select which address binding to use ?
Actually, even the most recent OS uses all the binding/linking types. It isn't really a matter of the OS but mostly a matter of user mode implementation. It is mostly the programmer which will decide which linking type to use but it isn't an explicit choice. It is chosen by the programmer implicitly by the way it programs in high level code. For example, if the programmer decides to use virtual functions in C++ then the address to jump to will be determined at runtime based on the type of the object referenced instead of the type of the reference. It is useful/recommended to know about linking and how it works to write more efficient code and to know what you are doing.
2- At compile time binding is used if the compiler knows in advance where the program will resides in main memory. How do the compiler know this future information ? Is it given by the programmer ?
It is quite complex and there is a lot to say about that. Today, you have paging that is always in use. A program has access to the whole address space. This means that a compiler doesn't have to care much about the position of an executable. It cares mostly about the start address and the rest is position independent or absolute. Position independent code doesn't even care all that much about the start address. The start address mostly provides a position to find the _start symbol but that's it. The rest of the code is using relative jumps to some position in the text segment and RIP-relative addressing to access global/static data.
It isn't that much about where the program will reside. It is a matter of if the function is present and implemented within your own code or in another library. If a function is present in another library, then the compiler will leave an unresolved symbol in the executable for the linker to resolve before execution. This is called dynamic linking an example of load time binding. The dynamic linker will find that dynamic library and place it somewhere in RAM. The dynamic linker will resolve where to jump to get to that function.
3- Run time binding is used if the program will always change his location during execution time . Is for example swapping and segmentation compaction are examples why the programs will change their location during execution , or they are different concepts here ?
There is no "program that will always change his location". Run-time binding is mostly present in C++ and is only a matter of virtual functions. All linking is done at compile time or at load time except for virtual functions. Virtual functions allow to call a function in an object by determining the type of the object referenced instead of using the type of the reference itself. This is used to provide polymorphism because the same function signature can have several implementations and which one to call will be determined based on the type of the object referenced. (For more info see: https://cs.stackexchange.com/questions/145444/what-attributes-are-bound-statically-vs-dynamically/145470#145470)

How can I compile, run AML with ACPI, or how should I utilize ACPI functions?

I'm trying to write a kernel and plan to use ACPI on some issues (e.g. identify interrupt source on APIC).
However, I'm really a beginner on this, I read the related documentation and still do not have any clue on how to configure and use ACPI functions.
I have some basic understanding that:
1, there are some ACPI tables will be mapped in memory space, within which DSDT and SSDT will provide some definition blocks.
2, The definition block are AML code
3, I can retrieve some information directly from ACPI tables (e.g. I/O APIC base address)
4, Further information some times need to run ACPI objects.
These are basically my understanding about ACPI. However, how should I use AML code, how should I run ACPI objects. I do not have a clue.
So if any one can provide a basic structure of how this mechanism works, how some basic functions provided by ACPI can be realized by OS??
Thanks a lot! I'll keep reading the documentation and try to find some thing that can help me on understanding it.
My advice is:
a) If you're a beginner, implement support for "PIC chips" while taking into account future support for things like IO APIC and MSI but not implementing that support yet (e.g. just dummy stubs, etc); and then worry about adding support for IO APICs (and MSI) and ACPI later (e.g. after most of your OS has been done, including device drivers, file systems, etc). Note that this is a big part of why I advocate a "kernel tells device driver which resources it should use" approach (rather than a "device driver tells the kernel which resources it wants" approach) - so you can add support for IO APIC and MSI later without touching any of the code for any of the device drivers.
b) For ACPI's AML; it's a nasty festering mess. Specifically, the OS has to tell AML what the OS is (e.g. using an \_OS object in AML to tell AML the operating system's name), if the OS isn't recognized by the computer's AML then the AML will typically fall back to a crippled "bare minimum functionality" mode, and the AML for lots of computers will only recognize (various versions of) Windows. The result is that to use the full functionality provided by AML your OS has to pretend that it is (a version of) Windows, and has to have the same behaviour as that version of Windows, which is not well documented (e.g. not included in the ACPI specs at all) and not easily discovered by "trial and error" techniques. If that's not bad enough; various computers have buggy AML, and you need "who knows how many" workarounds for these bugs. The most practical way to work around this problem is by relying on a well-tested code written by other people. More specifically; you will probably want to port ACPICA (see https://acpica.org/ ), which is an open-source and OS-independent implementation of ACPI that includes an AML interpreter and hides/abstracts a lot of the pain.
If you are working with linux, try the following (as root), it will give you a good start (you should install the distro relevant package, like acpica-tools):
$acpidump > dump.bin
$acpixtract -x dump.bin
(this will create a binary file for each table in the initial dump file. lots of ".dat" file)
$iasl -d *dat
(this will disassemble the binary files to human readable format)
you can also download intel's implementation for the iasl compiler from github (look it up. it is very easy to compile)

invoke coq typechecker from external programs

What would be the best way to interact with Coq from an external program? For example, let's say I want to programmatically generate programs / proofs in some language other than Coq and I just want to call Coq to typecheck them. Is there a standard way to do something like that?
You have a couple of options.
Construct .v files, invoke coqc, check the return code and parse the output of coqc.
This is, in some sense, the most stable way to interact with Coq. It has the most inter-version stability. It's also the most inflexible; you create a .v file, and check it all in one go.
For an example of this method, see my Coq bug minimizer (specificially get_coq_output in diagnose_error.py), which repeatedly makes small alterations to a .v file and checks to see that the alterations don't change the error message given by coqc.
Use the XML protocol to communicate with coqtop
This is the method used by CoqIDE and by upcoming versions of ProofGeneral. Logitext invokes from Haskell a custom patched version of coqtop with the pgip protocol, which was an earlier attempt at a more standardized way of communication with the prover (see this issue for more details).
This is becoming more stable, and gives more fine-grained control over what you want checked. For example, it allows you to check multiple proofs within a single session, which is important if you depend on a large library that takes time to load, and need to check many small proofs.
Write a custom OCaml toplevel wrapper for the interface to Coq that you want
The main example of this that I'm aware of is PIDEtop, which is used in the Coqoon Eclipse plugin. I suspect that some of the other entries in the GUI section of Related Tools use this method.
Note that coqtop is itself a toplevel wrapper in this style; the files in the toplevel/ folder of the Coq project are likely to be informative.
This gives you the most flexibility and reusability, at the cost of having to design your own protocol, or implement an existing protocol.
Write your external program in OCaml and link with Coq
Much like (3), this method gives you as much flexibility as you want. In fact, the only difference between this and (3) is that in (3), you separate out the communication with Coq into its own binary, whereas here, you fuse communication with Coq with the other functionality of your program. I'm not aware of programs in this style, though I believe coqchk may qualify, as I think it shares a couple of files with the Coq kernel (see the checker/ folder in the Coq codebase).
Regardless of which way you choose, I think that modelling off of existing projects will be more fruitful than making use of (as-yet incomplete) documentation on the various APIs and protocols. The API has been undergoing a lot of revision recently, in an attempt to get it into a reasonable and stable state, and the XML protocol has also been subject to recent improvements; #ejgallego has been the driving force behind much of these improvements.

Using Inline::CPP vs SWIG - when?

In this question i saw two different answers how to directly call functions written in C++
Inline::CPP (and here are more, like Inline::C, Inline::Lua, etc..)
SWIG
Handmade (as daxim told - majority of modules are handwritten)
I just browsed nearly all questions in SO tagged [perl][swig] for finding answer for the next questions:
What are the main differences using (choosing between) SWIG and Inline::CPP or Handwritten?
When is the "good practice" - recommented to use Inline::CPP (or Inline:C) and when is recommented to use SWIG or Handwritten?
As I thinking about it, using SWIG is more universal for other uses, like asked in this question and Inline::CPP is perl-specific. But, from the perl's point of view, is here some (any) significant difference?
I haven't used SWIG, so I cannot speak directly to it. But I'm pretty familiar with Inline::CPP.
If you would like to compose C++ code that gets compiled and becomes callable from within Perl, Inline::CPP facilitates this. So long as the C++ code doesn't change, it should only compile once. If you base a module on Inline::CPP, the code will be compiled at module install time, so another user never really sees the first time compilation lag; it happens at install time, just before the testing phase.
Inline::CPP is not 100% free of portability isues. The target user must have a C++ compiler that is of similar flavor to the C compiler used to build Perl, and the C++ standard libraries should be of versions that produce binary-compatible code with Perl. Inline::CPP has about a 94% success rate with the CPAN testers. And those last 6% almost always boil down to issues of the installation process not correctly deciphering what C++ compiler and libraries to use. ...and of those, it usually comes down to the libraries.
Let's assume you as a module author find yourself in that 95% who have no problem getting Inline::CPP installed. If you know that your target audience will fall into that same category, then producing a module based on Inline::CPP is simple. You basically have to add a couple of directives (VERSION and NAME), and swap out your Makefile.PL's ExtUtils::MakeMaker call to Inline::MakeMaker (it will invoke ExtUtils::MakeMaker). You might also want a CONFIGURE_REQUIRES directive to specify a current version of ExtUtils::MakeMaker when you create your distribution; this insures that your users have a cleaner install experience.
Now if you're creating the module for general consumption and have no idea whether your target user will fit that 94% majority who can use Inline::CPP, you might be better off removing the Inline::CPP dependency. You might want to do this just to minimize the dependency chain anyway; it's nicer for your users. In that case, compose your code to work with Inline::CPP, and then use InlineX::CPP2XS to convert it to a plain old XS module. Your user will now be able to install without the process pulling Inline::CPP in first.
C++ is a large language, and Inline::CPP handles a large subset of it. Pay attention to the typemap file to determine what sorts of parameters can be passed (and converted) automatically, and what sorts are better dealt with using "guts and API" calls. One feature I wouldn't recommend using is automatic string conversion, as it would produce Unicode-unfriendly conversions. Better to handle strings explicitly through API calls.
The portion of C++ that isn't handled gracefully by Inline::CPP is template metaprogramming. You're free to use templates in your code, and free to use the STL. However, you cannot simply pass STL type parameters and hope that Inline::CPP will know how to convert them. It deals with POD (basic data types), not STL stuff. Furthermore, if you compose a template-based function or object method, the C++ compiler won't know what context Perl plans to call the function in, so it won't know what type to apply to the template at compiletime. Consequently, the functions and object methods exposed directly to Inline::CPP need to be plain functions or methods; not template functions or classes.
These limitations in practice aren't hard to deal with as long as you know what to expect. If you want to expose a template class directly to Inline::CPP, just write a wrapper class that either inherits or composes itself of the template class, but gives it a concrete type for Inline::CPP to work with.
Inline::CPP is also useful in automatically generating function wrappers for existing C++ libraries. The documentation explains how to do that.
One of the advantages to Inline::CPP over Swig is that if you already have some experience with perlguts, perlapi, and perlcall, you will feel right at home already. With Swig, you'll have to learn the Swig way of doing things first, and then figure out how to apply that to Perl, and possibly, how to do it in a way that is CPAN-distributable.
Another advantage of using Inline::CPP is that it is a somewhat familiar tool in the Perl community. You are going to find a lot more people who understand Perl XS, Inline::C, and to some extent Inline::CPP than you will find people who have used Swig with Perl. Although XS can be messy, it's a road more heavily travelled than using Perl with Swig.
Inline::CPP is also a common topic on the inline#perl.org mailing list. In addition to myself, the maintainer of Inline::C and several other Inline-family maintainers frequent the list, and do our best to assist people who need a hand getting going with the Inline family of modules.
You might also find my Perl Mongers talk on Inline::CPP useful in exploring how it might work for you. Additionally, Math::Prime::FastSieve stands as a proof-of-concept for basing a module on Inline::CPP (with an Inline::CPP dependency). Furthermore, Rob (sisyphus), the current Inline maintainer, and author of InlineX::CPP2XS has actually included an example in the InlineX::CPP2XS distribution that takes my Math::Prime::FastSieve and converts it to plain XS code using his InlineX::CPP2XS.
You should probably also give ExtUtils::XSpp a look. I think it requires you to declare a bit more stuff than Inline::CPP or SWIG, but it's rather powerful.

VHDL beta function

A friend of mine needs to implement some statistical calculations in hardware.
She wants it to be accomplished using VHDL.
(cross my heart, I haven't written a line of code in VHDL and know nothing about its subtleties)
In particular, she needs a direct analogue of MATLAB's betainc function.
Is there a good package around for doing this?
Any hints on the implementation are also highly appreciated.
If it's not a good idea at all, please tell me about it as well.
Thanks a lot!
There isn't a core available that performs an incomplete beta function in the Xilinx toolset. I can't speak for the other toolsets available, although I would doubt that there is such a thing.
What Xilinx does offer is a set of signal processing blocks, like multipliers, adders and RAM Blocks (amongst other things, filters, FFTs), that can be used together to implement various custom signal transforms.
In order for this to be done, there needs to be a complete understanding of the inner workings of the transform to be applied.
A good first step is to implement the function "manually" in matlab as a proof of concept:
Instead of using the built-in function in matlab, your friend can try to implement the function just using fundamental operators like multipliers and adders.
The results can be compared with those produced by the built-in function for verification.
The concept can then be moved to VHDL using the building blocks that are provided.
Doing this for the incomplete beta function isn't something for the faint-hearted, but it can be done.
As far as I know there is no tool which allow interface of VHDL and matlab.
But interface of VHDL and C is fairly easy, so if you can implement your code(MATLAB's betainc function) in C then it can be done easily with FLI(foreign language interface).
If you are using modelsim below link can be helpful.
link
First of all a word of warning, if you haven't done any VHDL/FPGA work before, this is probably not the best place to start. With VHDL (and other HDL languages) you are basically describing hardware, rather than a sequential line of commands to execute on a processor (as you are with C/C++, etc.). You thus need a completely different skill- and mind-set when doing FPGA-development. Just because something can be written in VHDL, it doesn't mean that it actually can work in an FPGA chip (that it is synthesizable).
With that said, Xilinx (one of the major manufacturers of FPGA chips and development tools) does provide the System Generator package, which interfaces with Matlab and can automatically generate code for FPGA chips from this. I haven't used it myself, so I'm not at all sure if it's usable in your friend's case - but it's probably a good place to start.
The System Generator User guide (link is on the previously linked page) also provides a short introduction to FPGA chips in general, and in the context of using it with Matlab.
You COULD write it yourself. However, the incomplete beta function is an integral. For many values of the parameters (as long as both are greater than 1) it is fairly well behaved. However, when either parameter is less than 1, a singularity arises at an endpoint, making the problem a bit nasty. The point is, don't write it yourself unless you have a solid background in numerical analysis.
Anyway, there are surely many versions in C available. Netlib must have something, or look in Numerical Recipes. Or compile it from MATLAB. Then link it in as nav_jan suggests.
As an alternative to VHDL, you could use MyHDL to write and test your beta function - that can produce synthesisable (ie. can go into an FPGA chip) VHDL (or Verilog as you wish) out of the back end.
MyHDL is an extra set of modules on top of Python which allow hardware to be modelled, verified and generated. Python will be a much more familiar environment to write validation code in than VHDL (which is missing many of the abstract data types you might take for granted in a programming language).
The code under test will still have to be written with a "hardware mindset", but that is usually a smaller piece of code than the test environment, so in some ways less hassle than figuring out how to work around the verification limitations of VHDL.