开云体育

ctrl + shift + ? for shortcuts
© 2025 开云体育
How to convert Integer to numeric types? 2
The `valueOf` can be used to convert a numeric type into an integer, but how to do it in the reversed direction? For example, I want to build a module that wraps `mkSizedFIFO`, which takes a Integer parameter as it's depth. And in this module, I also want to define a register that holds a pointer like value. I hope the type of the register can be calculated from the fifo's depth. ``` module mkWrapSizedFifo#(Integer depth)(FIFOF#(tData)); FIFOF#(tData) innerFifo <- mkSizedFIFOF(depth); Reg#(Bit#(TLog#(depth))) idxReg <- mkFIFOF(0); // how to use depth here to define a type that can just hold the max value of depth? endmodule ``` Thanks!
Started by mmh_web @ · Most recent @
Deeply-Pipelined Modules 8
Hi, I want to write deeply pipelined modules for doing calculations, so the actual hardware is mostly a set of adders and multipliers with registers in-between. What's the best way to write this sort of thing in Bluespec? The best I can come up with is a bunch of FIFOs and rules to pass data between them, but that seems like it could become very boilerplatey very fast, especially given the need to add registers to pass data that's needed in future stages etc. So I either write a lot of struct definitions or use tuples (which seem a little clumsy in Bluespec syntax-wise). Example of the sort of maths I'm trying to implement is z = (z0 * a0 + z1 * a1 + z2 * a2) * w. -Emily
Started by Emily Schmidt @ · Most recent @
'Always' enabled for an import BVI module? 2
For import BVI, bsc insists that a method in the imported Verilog cannot omit both an output bus and an ENABLE signal (compile-time error message if we omit both). This makes general sense, because a method is either a value method (in which case it must have an output) or it must be an Action/ActionValue method (in which case it must have an ENABLE). However, if the Verilog module assumed an 'always enabled' semantics, it may not have an ENABLE input port. There seems to be no way to accommodate this. (Yes, one can use various wrappers/shims to work around this, but there seems no way directly to match the Verilog ports in the import BVI statement itself.)
Started by Rishiyur Nikhil @ · Most recent @
BSV Compilation Error 18
Hi All, I encountered an error during BSV compilation, even after increasing the steps in the makefile up to 60 million, as shown in the attached image. The error persists, stating that the maximum number of function unfolding steps has been exceeded. However, when I compile the same code using Bluespec version 2018 (Currently i am using 2022), the error doesn't occur. Could this issue be related to the version of Bluespec I'm using? I've also attached the relevant portion of the makefile where I adjusted the steps.
Started by saurav_gosh @ · Most recent @
More details about ModuleContext, ModuleCollect and CBus? 4
Hi, I have found those modules in the standard library, and they seems like 'black magic' in bluespec. And I want to learn more about the details. The most things that concerns me is: Are those modules still encouraged to be used in my projects? I have searched on github and it seems that seldom bluespec project use those modules. And there are many other related questions: 1. I have understand that the ModuleContext works like a factory that it takes in a "blueprint module", extract the key elements from the "blueprint", and then produce the real module instance. But there are no documents about what kinds of elements can be extracted from the "blueprint", and how can we operate on those extracted elements? I think its like Python's metaclass, or Rust's procdure macro. Do I need to learn some haskell to understand how those works? 2. I want to use CBus in one of my big projects that has very deep module hierarchical, to access config registers that spread everwhere. SInce the project is a huge one and Ihave a lot of config registers, so the CBus seems not to satifisy the timing requirements. So, are there any recommended ways to access a lot of registers in many deep nested modules and keep the module interface clean? I think the worst way is to write my own CBus that introduce pipeline stages when doing register access. 3. But there are still problems about the synthesize boundaries. If I use anything that rely on ModuleContext, it seems that it won't be (*synthesize*). And since my project is a huge one with deep hierarchical, there are many synthesize boundaries in the middle of the nested modules. If I use ModuleContext based approach, it seems would like to mess up the modules? Thanks.
Started by mmh_web @ · Most recent @
how to tell compiler that a group of if statement generated by for loop expanded are conflict-free? 3
suppose I want to write a MxN crossbar dispatch module, (the most important thing is that M, N are a parameter, I want to change M, N in different use case), the module has a input vector with size M and a output vector with size N (suppose M <= N). And there is another signal tells the module which input channel goes into which output channel, and I will make sure that no more than one element will go into the same output channel. I would write the following code: typedef Bit#(TLog#(N)) OutputChannelIdx; Vector#(M, FIFOF(Bool)) inFifoVec <- replicateM(mkFIFOF); Vector#(N, FIFOF(Bool)) outFifoVec <- replicateM(mkFIFOF); Vector#(M, OutputChannelIdx) destVec = some_value; for (Integer outputIdx = 0; outputIdx < valueOf(N); outputIdx = outputIdx + 1) begin for (Integer inputIdx = 0; inputIdx < valueOf(M); inputIdx = inputIdx + 1) begin if (destVec[inputIdx] == fromInteger(outputIdx)) begin fifoVec[outputIdx].enq(inFifoVec[inputIdx].first); end end end And of course the compiler won't happy with the enq, although in the inner for-loop, only one if statement will be activated. And I can't replace the for loop with a case statement here since I don't know how many case branch will have, it depends on M, N. Thanks.
Started by mmh_web @ · Most recent @
Clock domain crossing 5
Hi, I have a large design in which I am actually trying to pinmux the JTAG IO pins with GPIOs. During that process, since the JTAG is in different clock domain I am facing issues with connection. As per the design specs, I don't need to take care of the domain crossing. To achieve that, I found that I need to use mkNullCrossingWire. But I am facing issues if I use that. Can anyone help me to fix this? I checked #33 and #637. I see that the solution is to pass the values as module paramters. But in my case, I am not sure how to do that. I have attached a simpler version of the code where the same problem is replicated. This simpler design resembles the Testbench as the top module (SoC), mod1 as the pinmuxing module and mod2 to be the JTAG module. Changing the Wires() in mod1.bsv to registers works. But I don't want registers there. I want them to act as just a simple connection from the Testbench to mod2. ``` Testbench.bsv package Testbench; import Clocks :: *; import BUtils :: *; import mod1 :: *; import mod2 :: *; interface Ifc_Testbench; method Bit#(1) out; method Action ma_in (Bit#(1) in); endinterface (*synthesize*) module mkTestbench(Clock tck_clk, Reset trst, Ifc_Testbench ifc); let curr_clk <- exposeCurrentClock; let curr_rst <- exposeCurrentReset; Ifc_mod1 mod1 <- mkmod1; Ifc_mod2 mod2 <- mkmod2(clocked_by tck_clk, reset_by trst); ReadOnly#(Bit#(1)) cr_val_in <- mkNullCrossingWire(clocked_by tck_clk, reset_by trst, curr_clk, mod2.out); ReadOnly#(Bit#(1)) cr_val_out <- mkNullCrossingWire(tck_clk, mod1.val_out); rule connect_mods_out; mod1.val_in(cr_val_in); endrule rule connect_mods_in; mod2.ma_in(cr_val_out); endrule method out = mod1.pad_out; method Action ma_in (Bit#(1) in); mod1.pad_in(in); endmethod endmodule endpackage ``` ``` mod1.bsv package mod1; interface Ifc_mod1; method Bit#(1) val_out; method Action val_in (Bit#(1) in); method Bit#(1) pad_out; method Action pad_in (Bit#(1) in); endinterface module mkmod1(Ifc_mod1); Wire#(Bit#(1)) wr_val_in <- mkDWire(0); Wire#(Bit#(1)) wr_val_out <- mkDWire(0); Wire#(Bit#(1)) wr_pad_in <- mkDWire(0); Wire#(Bit#(1)) wr_pad_out <- mkDWire(0); rule rl_connect_in; wr_val_out <= wr_pad_in; endrule rule rl_connect_out; wr_pad_out <= wr_val_in; endrule method pad_out = wr_pad_out; method Action pad_in (Bit#(1) in ); wr_pad_in <= in; endmethod method val_out = wr_val_out; method Action val_in (Bit#(1) in ); wr_val_in <= in; endmethod endmodule endpackage ``` ```mod2.bsv package mod2; interface Ifc_mod2; method Bit#(1) out; method Action ma_in (Bit#(1) in); endinterface module mkmod2(Ifc_mod2); Reg#(Bit#(1)) rg_in <- mkReg(0); Reg#(Bit#(1)) rg_out <- mkReg(0); rule rl_connect; rg_out <= rg_in; endrule method out = rg_out; method Action ma_in (Bit#(1) in ); rg_in <= in; endmethod endmodule endpackage ```
Started by mounakrishna27121999@... @ · Most recent @
Contribution to AXI4 Fabric
AXI4 Fabric related code is in public domain due to its inclusion in multiple projects (e.g. Flute,Piccolo etc) Is there any plan to formally release it as a part of the github::B-Lang-org organisation. If I want to contribute bug fixes/enhancement to it, Which repo do I submit it to?
Started by vijayvithal jahagirdar @
An ActionValue output in rule firing condition. 6
Hi, I would like to use the output (return value) of an ActionValue method in a rule firing condition. How can I do this?
Started by mounakrishna27121999@... @ · Most recent @
Recursive Do Block 11
Hi! Long time Bluespec user (toy projects / research projects). What do I need to do to enable recursive bindings in a do-block? A.2.2 in BH_lang_ref says it's valid, but doesn't seem to be working for me. 1 package RecDo 2 ( f1, 3 f2 4 ) where 5 6 f1 :: Bit 1 -> ActionValue (Bit 1) 7 f1 a = return a 8 9 f2 :: ActionValue (Bit 1) 10 f2 = do 11 a <- f1 b -- Forward reference to 'b'. 12 b <- f1 a 13 return b bsc -verilog -bdir bdir -vdir vdir -u -remove-dollar RecDo.bs checking package dependencies compiling RecDo.bs Error: "RecDo.bs", line 11, column 10: (T0004) Unbound variable `b' make: *** [Makefile:14: recdo] Error 1 Cheers! Tom Hawkins
Started by Tom Hawkins @ · Most recent @
Asynchronus Reset for BypassFIFO and PipelineFIFO 3
Hi all, My design requires an asynchronous reset in the Processor IP. However, the design includes BypassFIFO and PipelineFIFO modules, which, when generated into Verilog, use synchronous resets by default. Is there a way to generate the RTL with these modules with asynchronous resets? Please suggest. Thanks in advance
Started by saurav_gosh @ · Most recent @
Why is vBRAM1's put CF read? 3
Replying to myself, much later: I'm still not sure why this scheduling is correct, but I have some ideas. First off, I believe this is irrelevant for the higher level FIFO'd BRAM modules, since the additional control logic they add is built around Regs and FIFOFs, and their scheduling annotations end up imposing the same write-after-read scheduling on the BRAM primitive method calls. So that leaves just the primitive BRAMCore modules, whose scheduling annotations permit read and put to execute in any order. This would allow the compiler to generate a conceptually invalid execution order in the guarded atomic actions model, where a put executes and overwrites the data presented to a later read - same as if a Reg write were allowed to proceed before a read of that Reg. My two hypotheses for why this is okay: That's just the point of BRAMCore, it's an unguarded wrapper around raw Verilog and by design the user of that module MUST bring their own control logic to impose correct scheduling between put and read. Perhaps there are devices out there with block RAMs that have put SB read semantics (I suppose that'd be completely unregistered combinatorial memory?...), and thus BRAMCore wants to let you express those? (however, if so, that seems to conflict with the (*reg*) annotations in the next point) In the BVI import, I see that some of the ports have a (*reg*) annotation. The docs aren't very explicit about what this tells the compiler beyond an informational "these ports are internally registered". Does bsc perhaps use these annotations to infer that a Reg-like schedule is required, and methods connected to (*reg*) ports should SA non-registered methods? I suppose the third hypothesis is that the vBRAM schedules that mark put CF read are incorrect, but given my current BSV skills I'm inclined to assume that I don't understand a subtlety of BVI imports or guarded atomic actions. - Dave
Started by David Anderson @ · Most recent @
BVI wrapper over systemverilog module with a struct port.
I have a systemverilog module with struct types in the IO list, e.g. see line 29 &30 of https://github.com/jahagirdar/peakrdl-bsv/blob/main/example/some_register_map.sv I have created a Bluespec struct with the same members e.g. see https://github.com/jahagirdar/peakrdl-bsv/blob/main/example/some_register_map.bsv line 310 which corresponds to line 29 of the verilog file. How do I bind the elements of bsv struct to the corresponding elements of sv struct in my import bvi?
Started by vijayvithal jahagirdar @
Why is vBRAM1's put CF read?
I'm writing some BSV wrappers for some FPGA primitives, in particular a dual-ported block RAM (I need to precisely control the timing and wiring, rather than rely on inference from abstract BRAMs). This is my first time writing BVI modules and layering Bluespec semantics on top of Verilog, so I'm leaning on the Bluespec standard library modules as a guide, in addition to the documentation. When it comes to scheduling annotations, I'm confused by vBRAM1 in BRAMCore.bsv. It states: schedule (put, read) CF (read); From the documentation, I expected this annotation to instead be: schedule (read) CF (read); schedule (read) SB (write); Assuming an unpipelined vBRAM1, the behavior at the Verilog level seem (to me) to match that of a register, and so reads should execute before writes to match how regular synchronous logic behaves. I assume that my mental model for scheduling is off somehow, can someone help me understand where I'm going astray? Why do vBRAM1 and Reg disagree on read vs. write scheduling? If a concrete piece of code helps, the BVI module I'm defining it at https://git.sentinel65x.com/dave/gary/src/branch/main/lib/ECP5_RAM.bsv#L293 . The scheduler annotations are at the end of the module. Ignoring the esoteric config parameters (limited data widths, write-through modes, chip select and so on), the underlying hardware block behaves like BRAM2.v: registered inputs, 1-cycle operation latency, optional output register for an extra cycle of latency. Thanks, - Dave
Started by David Anderson @
BDPI in BH Syntax 2
I haven't been able to figure out how to import C functions in Bluespec Classic syntax. For example, I wanted to convert these [CBindings.bsv](https://github.com/ThePerfectComputer/MannaChip/blob/main/bsv/CBindings.bsv) to BH.
Started by Yehowshua Immanuel @ · Most recent @
FIRRTL or RTLIL(Yosys ilang) backend emitter
Say I wanted to have bsc emit RTLIL or FIRRTL? Where would I start poking at to modify backend passes?
Started by Yehowshua Immanuel @
Asynchronus Reset Generation
In my design previously i was using Synchronus Reset for all the instance in the block, Now i want to change reset to Asynchronus Reset as i already generated the Asynchronus Reset in the processor top and given to all the submodules for registers i found that all i need to change from mkReg -> mkRegA it works but how about the other blocks FIFOs, RegFiles,Vector of Reg etc. is there any way to change the behaviour of the design that completely work on the Asynchronus Reset.
Started by firoz @
BSV Formatter 4
Are there any tools for formatting Bluespec source code?
Started by Yehowshua Immanuel @ · Most recent @
Are there any documents about the naming convension of the identifiers in generated verilog files? And how to read thoes generated files? 6
First, I noticed that some signals has prefix like MUX, IF, but some other signals does not, so when will the bsc generate some signals with prefix? Second, a lot of signals is named by an index number, like `hxxxxxx`, how can I figure out what the coresponding signal in the original BSV files? Third, can I forec bsc to keep a BSV variable's name not changed in the output verilog file? this sometimes can help fix timing a lot. Thanks.
Started by mmh_web @ · Most recent @
Negative Clock Edge Registers 4
Hello, I'm having an issue trying to get Bluespec Verilog to insert registers that are clocked on the negative edge of a the domain clock. I've used the mkClockInverter module, synchronizers and other sort of tricks to try and get the desired result I'd like. Most of my first attempts resulted in errors out of the compiler talking about clock ancestry (I don't expect this since they should have the same ancestor), reset synchronizers (which I did try to fix), or just simple type errors looking to get around this. I finally settled on using the mkSyncBit05 module with both clocks being the same domain SyncBitIfc #(Bit #(1)) rg_din <- mkSyncBit05(sclk, srst_b, sclk); . This kind of makes these a bit wonky, but it seems to work for my purpose. My question to you all is: what is the Bluespec recommended way to properly implement registers that utilize the falling edge of a clock? Thanks!
Started by Michael Jaggers @ · Most recent @
Current Image
Image Name
Sat 8:39am