feature (?) in HelloWorld

"Soft PrOcessor Core" - or "SPOC"

feature (?) in HelloWorld

Postby raalst » Fri Oct 14, 2005 9:30 am

the hello world contains this :
[quote]// check the RS-232 TX busy bit
do #0x1000 -> RA0
LoopTxD_ready:
do.bit @
jmp.z=1 #LoopTxD_ready
[/quote]

am I correct in assuming that the second test of the bit
actually tests memory bit 0x1001 ?
The docs seem to suggest that acessing a memory location auto- increments the RA/WA registers.
since the memory decode is so crude, it doesn't matter for hello
world, but working from that I added some functionality which seemed
to have a mind of it's own.

This autoincrement would also explain why I cannot find an increment operation acting on the CS pointer while it outputs all the chars in sequence.

maybe this should be explained in a bit more detail in versio 2.0 of the docs.

Regards,
Ronald
Regards,
Ronald van Aalst
raalst
 
Posts: 13
Joined: Tue Sep 27, 2005 7:28 pm
Location: netherlands

maybe someone can help with this code :

Postby raalst » Fri Oct 14, 2005 9:52 am

hello all, in order to use spoc to create a eprom programmer,
I need it to consume commands and return data.
so I modified hello world, combining it with the other snippets
of spoc code the site provides.

I modified helloworld into :
// Example of spoc processor routine
// This displays periodically the string "Hello world!" on an RS-232 terminal
Begin:
// initialize the char to "A" just to be sure
do.byte #0x41 -> A
// wait for char received, signal on address 3000
Loop_Ch_recv:
do.word #0x3000 -> RA0
do.bit @
jmp.Z=0 #Loop_Ch_recv
// read the inchar into accumulator
do.word #0x2000 -> RA1
do.byte @ -> A
SendReply:
do.word #0x1000 -> WA0
do.byte A -> @ // transmit one byte out of RS-232 TX
// check the RS-232 TX busy bit
LoopTxD_ready:
do.word #0x1000 -> RA2
do.bit @
jmp.Z=1 #LoopTxD_ready
Senddot:
do.word #0x1000 -> WA0
do.byte #0x2E -> @ // transmit "." out of RS-232 TX
// check the RS-232 TX busy bit
Loop2TxD_ready:
do.word #0x1000 -> RA3
do.bit @
jmp.Z=1 #Loop2TxD_ready
final:
// once string completely sent, delay before sending again
Delay:
// do.dw #200000 -> A
//DelayLoop:
// dec.dw A
// jmp.z=1 #DelayLoop
jmp #Begin

// that's all folks


this does not work. no reaction whatsoever.
When I use the "wait for TxDbusy" construct from hello world,
after i press one "s" I get an endless stream of s.s.s.s.s.s.s
(I also had the double latency in the reads then, but the hello
world does not use that double latency as well...)

I do not see what is wrong. maybe you guys do ?
I run it on a pluto II

the associated top .V code is :
// Spoc test

module spoc2(
clk, TxD, RxD, LED
// spoc_ExecuteOpcode_Done, spoc_WriteData, spoc_WriteEnable, spoc_ReadData, spoc_WriteAddress, spoc_ReadAddress
);
input clk;
input RxD;
output TxD;
output LED;

//output spoc_ExecuteOpcode_Done, spoc_WriteData, spoc_WriteEnable, spoc_ReadData; output [15:0] spoc_WriteAddress, spoc_ReadAddress;

wire spoc_ExecuteOpcode_Done, spoc_WriteData, spoc_WriteEnable;
reg spoc_ReadData;
wire [15:0] spoc_WriteAddress, spoc_ReadAddress;
spoc spoc1(
.clk(clk), .ExecuteOpcode_Enable(1'b1), .ExecuteOpcode_Done(spoc_ExecuteOpcode_Done),
.WriteAddress(spoc_WriteAddress), .WriteData(spoc_WriteData), .WriteEnable(spoc_WriteEnable),
.ReadAddress(spoc_ReadAddress), .ReadData(spoc_ReadData)
);

///////////////////////////// the example
//reg TxD_start;
//reg [7:0] TxD_data;
//wire TxD_busy;
//async_transmitter asyncTX(.clk(clk), .TxD_start(TxD_start), .TxD_data(TxD_data), .TxD(TxD), .TxD_busy(TxD_busy));
//
//always @(posedge clk) if(spoc_WriteEnable) TxD_data[spoc_WriteAddress[2:0]] <= spoc_WriteData;
//always @(posedge clk) TxD_start <= spoc_WriteEnable & spoc_WriteAddress[2:0]==3'h7;
//assign spoc_ReadData = TxD_busy; // ? no 2 levels of clock latency ?
/////////////////////////////

// transmitting stuff
reg TxD_start;
reg [7:0] TxD_data;
wire TxD_busy;
async_transmitter asyncTX(.clk(clk), .TxD_start(TxD_start), .TxD_data(TxD_data), .TxD(TxD), .TxD_busy(TxD_busy));

always @(posedge clk)
if(spoc_WriteEnable)
if(spoc_WriteAddress[15:12]==4'h1) TxD_data[spoc_WriteAddress[2:0]] <= spoc_WriteData;
always @(posedge clk) TxD_start <= (spoc_WriteEnable & (spoc_WriteAddress[2:0]==3'h7) & (spoc_WriteAddress[15:12]==4'h1));

// receiving stuff
wire RxD_data_ready;
wire [7:0] RxD_data;
reg [7:0] lastrcvd;
async_receiver RX(.clk(clk), .RxD(RxD), .RxD_data_ready(RxD_data_ready), .RxD_data(RxD_data));

always @(posedge clk) if (RxD_data_ready) lastrcvd <= RxD_data;

assign LED = RxD_data_ready || TxD_busy;

// reading in the data
// we need 2 registers to create 2 levels of clock latency
// reg spoc_ReadData_reg;

always @(posedge clk) // one level of clock latency
case(spoc_ReadAddress[15:12]) // coarse address decoding
4'h1: spoc_ReadData <= TxD_busy; // is on address 1000 hex
4'h2: spoc_ReadData <= lastrcvd[spoc_ReadAddress[2:0]]; // is on address 2000 hex
4'h3: spoc_ReadData <= RxD_data_ready; // is on address 3000 hex
default: spoc_ReadData <= 1'b0;
endcase

// second level of clock latency
//always @(posedge clk) spoc_ReadData <= spoc_ReadData_reg;

endmodule
Regards,
Ronald van Aalst
raalst
 
Posts: 13
Joined: Tue Sep 27, 2005 7:28 pm
Location: netherlands

clock latency on read

Postby raalst » Fri Oct 14, 2005 9:57 am

I tested with and without the second latency added, but no change in behaviour.
Regards,
Ronald van Aalst
raalst
 
Posts: 13
Joined: Tue Sep 27, 2005 7:28 pm
Location: netherlands

Postby fpga4fun » Fri Oct 14, 2005 11:21 pm

// check the RS-232 TX busy bit
do #0x1000 -> RA0
LoopTxD_ready:
do.bit @
jmp.z=1 #LoopTxD_ready


With this code, you test bit location 0x1000.
But after the test, the RA0 register now contains value 0x1001
fpga4fun
Site Admin
 
Posts: 837
Joined: Thu Sep 18, 2003 6:47 am

Postby fpga4fun » Fri Oct 14, 2005 11:24 pm

Sorry I cannot help you more right now, nor work on Spoc, I'm busy supporting Xylo and all the other new stuff on the site.
fpga4fun
Site Admin
 
Posts: 837
Joined: Thu Sep 18, 2003 6:47 am

fair enough, others' help welcome

Postby raalst » Mon Oct 17, 2005 10:09 am

Jean,

Fair enough,
I was hoping to attract/contact some others using the spoc.

so anybody taking a shot at spoc, feel free to have a look at my
attempt posted above !

Regards,
Ronald
Regards,
Ronald van Aalst
raalst
 
Posts: 13
Joined: Tue Sep 27, 2005 7:28 pm
Location: netherlands

Postby outer_space2 » Mon Oct 17, 2005 4:36 pm

I'm going to get into spoc and FLASHY as soon as a number of other projects are finished.
outer_space2
 
Posts: 51
Joined: Sun Oct 09, 2005 1:05 pm

solved it !

Postby raalst » Mon Oct 17, 2005 8:43 pm

the solution is already hinted on in
http://www.fpga4fun.com/forum/viewtopic.php?t=157

the main issue is that the RxD_data_ready is too short lived to be
noted by a CPU.

I added this code now, which solved the problem :
Code: Select all
// providing a longer lasting signal for the cpu to come and get the data
reg comeandgetit;
reg overrun;
always @(posedge clk)
   overrun <= (overrun || ((comeandgetit==1'b1) & RxD_data_ready));
always @(posedge clk)   
   comeandgetit <= (RxD_data_ready || ((comeandgetit==1'b1) & !((spoc_ReadAddress[15:12]==4'h2) & (spoc_ReadAddress[2:0]==3'h7))));

assign LED = comeandgetit;


it basically says :
comeandgetit is high from RxD_data_ready until the CPU has read the last bit of the received data character
(overrun is high from the moment RxD_data_ready is received while comeandgetit still high).
The LED is used as a debugging signal
Regards,
Ronald van Aalst
raalst
 
Posts: 13
Joined: Tue Sep 27, 2005 7:28 pm
Location: netherlands


Return to Spoc