Release 2019–02–27
This is pure quick bug fix for invalid code
Fixed NullPointerException when compiling invalid code.
Release 2018–04–27
I kept working on stuff, but didn’t have the time to do a proper release with writing the notes and doing enough testing to feel confident about it. So this release may have some issues, but it also solves quite a few :)
I added the option to also create C++ code. So with -type cpp you can now get C++ compatible simulation code.
It is now possible to reference constants from the module it is in.
In addition to generating registers, you can now also add ram blocks. Those multi-port memory blocks can be read/written from the APB bus just like regular memory and read/written from the fabric with their special names.
Release 2017–06–01
This is obviously a big release. PSHDL has matured quite a bit in the past years and many small bugs have been fixed.
Any register can now have additional delays. You simply specify the amount of delay that is needed and PSHDL generates a chain of registers for you.
register(delay=13) bit<16> data13Dly=data;
If you want to delay by a large amount, it makes sense to use block-RAM for it.
@ramDelay
@VHDLNoExplicitReset
register(delay=2044) bit<16> data13DlyRam=data;
In order to optimize the address logic, the next power of two is used as RAM size.
If you really want to use the size given, you can add the “tight” argument to
the @ramDelay
annotation.
@ramDelay("tight")
@VHDLNoExplicitReset
register(delay=2044) bit<16> data13DlyRam=data;
Occasionally a simple block-RAM is not sufficient. Sometimes data arrives from a
different clock-domain, or has a different size. The @memory
annotation
allows to specify a common shared variable between two registers.
WARNING: There are still some issues with memories in PSEX simulation.
module DualPortMultiClockTest {
const uint32 WIDTH=2048;
in bit readClk;
in bit writeClk;
@memory("pxMem")
register(clock=writeClk) uint<16> pixels_write[WIDTH];
@memory("pxMem")
register(clock=readClk, resetValue={1,2,3}) bit<64> pixels_read[WIDTH/4];
in uint<11> write_address;
in uint<9> read_address;
in bit write_enable;
out bit<64> read_data;
in uint<16> write_data;
if (write_enable){
pixels_write[write_address]=write_data;
}
read_data=pixels_read[read_address];
}
If you have a bus declaration with a register it might be tricky to see if a
write has occurred to that address. With the writtenFlag
you can now get a
special variable that indicates a write.
It is now also possible to define constants. There are three special constants:
$date
, $time
, $checksum
. The first two will indicate when the bus
has been generated, and the later one is a checksum over the bus configuration.
This is useful to check on the CPU if the drivers actually match the fabric.
In addition prefix can be used to generate unique method names, such that you
can have multiple busses in one system. Normally when inlining the bus it
automatically defines the default clock. With the defaultClock
attribute it is
now possible to disable that feature. The same goes for the reset, which uses
defaultReset
argument.
include CamDDRBus cpu=generate apb(prefix="cam_ddrArbiter", defaultClock=false)<[
row startAdress{
rw register uint<32> startAddress;
}
row ^ctrl {
rw register bit enableRecording;
fill;
rw register uint<1> useAddress;
}
row ^info {
r register uint<8> fval_count writtenFlag;
r register uint<23> replyCounter;
rw register bit overflowed;
}
row ^toggles {
r register uint<16> lval_count writtenFlag;
r register uint<16> dval_toggle_count writtenFlag;
}
row ^stats {
r register uint<32> dval_count writtenFlag;
}
row constants {
const<16> 0xCAFE;
const<16> 0xBEEF;
}
column dateTime {
const $date;
const $time;
const MAGIC 0xDEADBEEF;
const 0xCAFE_BABE;
}
memory {
ctrl;
startAdress[2];
info;
toggles;
stats;
dateTime;
constants;
const $checkSum;
}
]>;
Of course PSHDL will also generate getter methods for the constants. Especially
the validateCheckSumMatch
is of special interests. It checks if the checksum
defined in the header file, matches the one in the fabric. A mismatch means that
the software or the fabric is out of date.
cam_ddrArbiter_getDateDirect(CAM_DDR, 0, &date);
cam_ddrArbiter_getTimeDirect(CAM_DDR, 0, &time);
cam_ddrArbiter_getCheckSumDirect(CAM_DDR, 0, &checksum);
bool checkSumMatch=cam_ddrArbiter_validateCheckSumMatch(CAM_DDR);
printf("FPGA Fabric from %08X at %06X checkSum:%08X match:%s"NL, date, time, checksum, checkSumMatch?"true":"false");
In addition you can now define PSHDL_NL
which is the default new line string
that will be used in the bus print code.
Two new functions have been introduced: msbOf()
and widthOf()
. They return
the highest possible index of any variable or the width of the variable.
@VHDLNoExplicitReset
variables now has a type cast.Release 2016–04–03
Continued the work on the Assert and printf. Also added new export function
<>
at the end to export the index type.
(@VHDLType("ieee.std_logic_1164.std_logic_vector<>")
)When a module is instantiated, its ports can automatically be exported. That means, a variable of the same name and type is created, and the exported port is assigned to it. As such an exported port looks like a signal originally from the module.
This is useful for cases where you want to export many signals, such as a bus.
You can export ports by a matching regular expression.
module SPIDebug {
in bit spi_mosi, spi_ss, spi_sclk;
out bit spi_miso;
//Something useful here
}
module Test {
SPIDebug dbg;
//This exports all ports that match starts with spi_
export dbg.spi_*;
}
Or you can group those ports together logically, and export that group:
module SPIDebug {
@portGroup("SPI")
in bit mosi, ss, sclk;
@portGroup("SPI")
out bit miso;
//Something useful here
}
module Test {
SPIDebug dbg;
//This exports all ports that have a @portGroup("SPI") annotation
export dbg./SPI/;
}
Unfortunately I found a code generation problem. When a incrementing or decrementing range is used, the resulting bit vector was one bigger than I wanted.
Example:
a{7+:10} //is now a bit-vector a{7:16} instead of a{7:17}
In addition to that I improved the code validation for those ranges.
Release 2015–11–29
Internal new release, nothing changed.
Release 2015–11–29
Function calls can now be executed from the simulation. That means that I can implement printf and alike from the simulation. It also means that assertions can now be used from test benches.
Release 2015–05–11
Fixed a bug for simulation casts from bit<>
to int<>
. Thanks Joerg for reporting it.
You can now create a ChangeAdapter that tracks what Variables have changed. You can then listen to those changes. One of those listeners is an experimental VCD printer. Here is how you can use it:
public static IHDLInterpreter interpreterWithVCD(ExecutableModel em, boolean disableEdge, boolean disableOutputLogic) throws Exception {
ValueChangeDumpListener vcdDump = new ValueChangeDumpListener(System.out, em.variables, ".*");
JavaCodeGeneratorParameter jcgParam = new JavaCodeGeneratorParameter(em).setPackageName("test").setUnitName("testClass");
JavaCodeGenerator jc = new JavaCodeGenerator(jcgParam);
CharSequence changeAdapter = jc.createChangeAdapter(true, Predicates.alwaysTrue());
try (JavaClassRuntimeLoader jcl = new JavaClassRuntimeLoader()) {
IHDLInterpreter interpreter = jcl.compileAndLoad(jcgParam.javaClassName(), jc.generateMainCode(), disableEdge, disableOutputLogic).newInstance();
return jcl.compileAndLoadChangeAdapter(jcgParam.javaChangeAdapterName(true), changeAdapter.toString(), interpreter, vcdDump).newInstance();
}
}
Release 2015–04–11
Made PSHDL Java 7 compatible again.
Release 2015–03–31
Implemented dynamic bit access in interpreters
Release 2015–03–30
Only a minor bug fix for any-types.
Any-type declaration could have caused an infinite loop in the compiler
Release 2015–03–30
Only a minor bug fix for any-types.
Any-type declaration could have caused wrong type inference
Release 2015–03–30
This release adds an interesting new feature: Any-types.
int<8> z=5;
int<> x=z; //x will become int<8>
bit<13> q=(uint<>)z+13; //Same as a cast (uint<8>)
Rules:
Another important feature is the deprecation of int/uint
in favor or the more precise uint32/int32
. This is to avoid unwanted truncations. Some people were falsely thinking that (int)x
is simply changing x
to an int
interpretation, but in reality it might also have clipped it to 32 bit. Of course int<42>
still remains valid.
Release 2015–03–29
The code generators now correctly handle dynamic bit accesses.
module testDynamicBitAccess {
@range("<64") in uint32 selectBit;
in bit<64> data;
out bit<64> writeData;
writeData{selectBit}=data{selectBit};
out bit selectedBit=data{selectBit};
}
Fixed a minor bug when parsing code
Release 2015–02–19
Some more comment transfers for VHDL. Allowed comment styles:
//regular comment
///Documenting comment (goes to entity) above module/variable
/** Documenting block comment above module/variable */
out int32 o; ///< Documenting comment behind declaration
out int32 o; /**< Documenting comment behind declaration */
Fixed a bug that caused wrong simulation results when a block within a switch case was used.
Release 2015–01–21
Comments and JavaDoc style comments are now transferred to VHDL at proper places. JavaDoc style comments are used in entity declaration, while regular comments are in the architecture.
Release 2015–01–08
Some bugs related to multi-dimensional arrays have been fixed. Thank Thilo for reporting. Additionally instead of uint you can now write uint32 to clarify that the uint (without any width) has in fact only 32 bits. Uint without any width, will be deprecated in the next minor release in favor of uint32.
Release 2014–11–24
This is a minor release that fixes two bugs reported by @pitwuu. Thanks for that!
Release 2014–09–12
This is a big release. It contains a completly rewritten way of handling functions, and significantly improved performance in simulation. I personally think that from now on it will be much harder to introduce any more significant performance improvements.
Release 2014–08–17
Fixed some heisenbugs
Release 2014–08–15
Hot fix for some problems with the generated Go code
Release 2014–08–15
The Go Code passes all unit tests and is now available via command line and REST API.
Release 2014–08–13
A new Dart Code generator and a new Go language generator have been added. Also various bugs with the Dart code have been addressed. The go code is currently not public as there are still some known issues.
From the C code you can now get from a String name the index.
Major change getOutput will now sign extend signed types, even when they are returned as unsigned
Release 2014–08–08
A new C Code generator has been released! This now includes generation of proper header files :)
Release 2014–08–04
This was a server side hot fix
Release 2014–08–03
Release 2014–08–01
Release 2014–07–26
Release 2014–07–23
Released 2014–07–11
Released 2014–06–24
This was a hot-fix for a problem with the REST API.
Released 2014–06–22
Released 2014–06–19
Released 2014–06–18
Released 2014–06–17