YosysHQ / yosys

Yosys Open SYnthesis Suite
https://yosyshq.net/yosys/
ISC License
3.49k stars 893 forks source link

ilang bnf #558

Closed dvc94ch closed 6 years ago

dvc94ch commented 6 years ago

If ilang is intended as an IR then it should have a bnf grammar. This is one I wrote for a racket parser which might serve as a starting point, but I'm sure it's still riddled with bugs.

#lang brag
;; design
design : autoidx module*
;; modules
module : attribute* /"module" name module-decl* /"end"
@module-decl : wire | cell | process | connection
;; wires
wire : attribute* /"wire" wire-prop* name
@wire-prop : width | input | output | inout
;; cells
cell : attribute* /"cell" type name cell-decl* /"end"
@cell-decl : parameter | connection

;; properties
name : IDENT
type : IDENT
attribute : /"attribute" IDENT STRING
;; design properties
autoidx : /"autoidx" INTEGER
;; wire properties
width : /"width" INTEGER
input : /"input" INTEGER
output : /"output" INTEGER
inout : /"inout" INTEGER
;; cell properties
parameter : /"parameter" IDENT INTEGER
connection : /"connect" IDENT signal

;; signal
@signal : constant | ref | concat
@constant : INTEGER | CONSTANT
ref : IDENT [/"[" INTEGER [/":" INTEGER] /"]"]
concat : /"{" signal* /"}"

;; process
process : attribute* /"process" name process-decl* /"end"
@process-decl : assign | switch | sync
;; assign
assign : /"assign" signal signal
;; switch
switch : attribute* /"switch" ref case* /"end"
case : /"case" [CONSTANT] process-decl*
;; sync
always : /"always"
init : /"init"
posedge : /"posedge" IDENT
negedge : /"negedge" IDENT
high : /"high" IDENT
low : /"low" IDENT
sync : /"sync" (always | init | posedge | negedge) update*
update : /"update" ref signal
(define-lex-abbrevs
  [integer unsigned-number]
  [constant (:or decimal-number
                 binary-number
                 octal-number
                 hex-number)]
  [decimal-number (:or (:seq (:? size) decimal-base unsigned-number)
                       (:seq (:? size) decimal-base x-digit)
                       (:seq (:? size) decimal-base z-digit))]
  [binary-number (:seq (:? size) binary-base binary-value)]
  [octal-number (:seq (:? size) octal-base octal-value)]
  [hex-number (:seq (:? size) hex-base hex-value)]
  [size (:seq non-zero-decimal-digit (:? (:+ (:or #\_ decimal-digit))))]
  [unsigned-number (:seq decimal-digit (:? (:+ (:or #\_ decimal-digit))))]
  [binary-value (:seq binary-digit (:? (:+ (:or #\_ binary-digit))))]
  [octal-value (:seq octal-digit (:? (:+ (:or #\_ octal-digit))))]
  [hex-value (:seq hex-digit (:? (:+ (:or #\_ hex-digit))))]
  [decimal-base (:seq #\' (:? (:or #\s #\S)) (:? (:or #\d #\D)))]
  [binary-base (:seq #\' (:? (:or #\s #\S)) (:or #\b #\B))]
  [octal-base (:seq #\' (:? (:or #\s #\S)) (:or #\o #\O))]
  [hex-base (:seq #\' (:? (:or #\s #\S)) (:or #\h #\H))]
  [non-zero-decimal-digit (:/ #\1 #\9)]
  [decimal-digit (:/ #\0 #\9)]
  [binary-digit (:or (:/ #\0 #\1) x-digit z-digit)]
  [octal-digit (:or (:/ #\0 #\7) x-digit z-digit)]
  [hex-digit (:or (:/ #\0 #\9) (:/ #\a #\f) (:/ #\A #\F) x-digit z-digit)]
  [x-digit (:or #\x #\X)]
  [z-digit (:or #\z #\Z #\?)])

(define ilang-lexer
  (lexer-srcloc
   [(eof) (return-without-srcloc eof)]
   [whitespace (token 'WHITE lexeme #:skip? #t)]
   [(from/stop-before "#" "\n") (token 'COMMENT lexeme #:skip? #t)]
   [constant (token 'CONSTANT (parse-vconstant lexeme))]
   [integer (token 'INTEGER (string->number lexeme))]
   [(from/to "\"" "\"") (token 'STRING lexeme)]
   [(from/stop-before (:or "\\" "$") whitespace) (token 'IDENT lexeme)]
   [(:or "autoidx" "attribute" "module" "wire" "cell"
         "parameter" "connect" "end" "process" "assign"
         "width" "input" "output" "inout" "sync" "always"
         "init" "posedge" "negedge" "high" "low" "update" "switch" "case")
    (token lexeme 'KEYWORD)]
   [(:or "{" "}" "[" "]" ":") (token lexeme 'SEPARATOR)]))
byzantic commented 6 years ago

Nice idea, but a bit indegestible as is ..

What about putting it into a form suitable for displaying as a railroad diagram, by using this site: http://www.bottlecaps.de/rr/ui

dvc94ch commented 6 years ago

Found this interesting tool k framework and thought I'd give it a try. It would allow defining the semantics and give a reference interpreter for ilang. I'm not sure yet what the semantics of a hardware description language are. It seems like currently semantics are defined in terms of the results from simulation, two designs that have the same waveform for all inputs are equivalent. Is there anything like synthesis semantics where the semantics are defined in terms of the cells it synthesizes? But having a railroad diagram is also a good idea

byzantic commented 6 years ago

Is there anything like synthesis semantics where the semantics are defined in terms of the cells it synthesizes?

Well .. yes .. that's the whole point of synthesis .. but not really done from the point of view of a fully formal approach; it is normally done in an ad-hoc manner.

The intermediate 'language' is intended as a bridge between the behavioural form of HDLs, and the highly specific behaviour of cell libraries. It needs to be both easy to map to cells, and easy to be translated to from behavioural constructs.

We will slowly see more formal methods applied to synthesis, but I suspect it will be a gradual process, since performance is acceptable at the moment. The best bang per buck comes from applying formal methods to behavioural proofs, which is indeed where Clifford seems to be working at the moment..

dvc94ch commented 6 years ago

Do hdl engineers think in terms of how a simulator works or in terms of the hardware they are trying to synthesize?

byzantic commented 6 years ago

Both.

The reason being that the two may not be quite the same; there are some constructs that can simulate differently from the synthesised logic. However, this is usually an error on the part of the designer, such as missing a term from a sensitivity list.

Ideally, you describe the hardware by thinking only about the eventual logic. In the early days of synthesis, this meant being aware of the constructs generated from each type of clause, as some produced deeper logic than others. These days, that doesn't matter so much, as applying timing constraints will cause even quite tortuous logic trees to me smashed down and optimised.

The purely behavioural code is used in testbenches.

On Tue, 5 Jun 2018 at 02:16, David Craven notifications@github.com wrote:

Do hdl engineers think in terms of how a simulator works or in terms of the hardware they are trying to synthesize?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/YosysHQ/yosys/issues/558#issuecomment-394549084, or mute the thread https://github.com/notifications/unsubscribe-auth/AcYJ7TTYglVzGf9CbxOhn7K47mTW0lRLks5t5dv7gaJpZM4UYDIQ .

dvc94ch commented 6 years ago

Here's a railroad pdf, generated from an antlr grammar. Shall I PR the antlr grammar and pdf? This version should be more or less correct since I based it on the bison parser instead of guessing by looking at a ilang file...

Interestingly ilang doesn't have an assert and assume statement.

ilang.pdf

sequencer commented 5 years ago

Hello, will ilang bnf being supported by yosys? Original AST can be a little hard for frontend/backend composing, if all language can be targeted to antlr, and use antlr lexer and parser, contributions could be much easier.